Autor Tema: Intermitentes moto.  (Leído 13110 veces)

0 Usuarios y 3 Visitantes están viendo este tema.

Desconectado ohsielos

  • PIC10
  • *
  • Mensajes: 21
Re: Intermitentes moto.
« Respuesta #15 en: 06 de Diciembre de 2010, 15:47:53 »
Hola, éste consume "mucho" (3w frente a los 21w de una lámpara incandescente) porque brilla mucho también, y quiero que se vea de lejos (cuando lo he mirado sin querer me ha dejado la vista chunga un rato), y la tulipa siempre se come algo de luz.

Concretamente es éste led el que he comprado, además de un 'driver' que le suministra la corriente justa a partir de 12 a 20v.

http://cgi.ebay.com/5p-3W-STAR-HIGH-POWER-AMBER-LED-LAMP-45lm-FREE-SHIPPING-/350084920256?pt=LH_DefaultDomain_0&hash=item5182aff3c0

He estado viendo el enlace de los circuitos y tal como están sí funciona: alimenta a 12v el circuito que está en el colector del transistor, pero lo que yo necesito es por un solo cable enviar los +12 al led y que por el casquillo de la lámpara vaya a masa y conduzca, el esquema sería el siguiente (perdona por la chapuza pero he modificado el del compañero con el paint).




Como ves en el esquema, cuando conduce el tr envía 12v al intermitente y de ahí a masa, como en todas las bombillas creo. Si lo pusiera en el colector necesitaría dos cables y aislar el portalámparas ya que ninguna pata iría a masa.

Otra cosa: esos pics 12F y 10F se programan con el TE-20?? Es un punto importante para no complicarme mas la vida.

Por cierto: el parpadeo es bastante 'natural', igual le acorto un poco el tiempo de apagado, pero se ve ya bastante 'legal'.

Voy a pasarme por el enlace del motero a ver que tal.
« Última modificación: 06 de Diciembre de 2010, 16:02:38 por ohsielos »

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Intermitentes moto.
« Respuesta #16 en: 10 de Diciembre de 2010, 07:07:24 »
En esta pag. explica como grabar PICs DE 8 PINES con el TE-20, espero te aclare dudas.

http://www.tarribot.com/?id=23&idm=1

En el circuito no se si has avanzado mucho, ya sabes como vas a convertir los 12V a 5V para alimentar el PIC, y que transistores vas a usar etc.

Estoy optimizando el programa haciendolo con desborde de TIMER, estos dias lo pondre por aqui, despues usas el que quieras, tambien estara en torno a 200 BYTES asi que te servira cualquier PIC, el que mas barato te salga, mas facil de conseguir...

Saludos

Desconectado ohsielos

  • PIC10
  • *
  • Mensajes: 21
Re: Intermitentes moto.
« Respuesta #17 en: 10 de Diciembre de 2010, 18:28:07 »
Hola de nuevo.
La alimentación lo tengo claro: con un regulador 7805 o 78M05, uno cualquiera ya que el pic apenas va a consumir. Después miraré el consumo máximo que puedo tener y ya me decido.
Entrarán los +12v de la batería que alimentará al pic via 7805 y saldrán hacia los intermitentes donde instalaré en cada uno el driver de 700mA (que le da igual que hayan 12 que 15v) y el led de 3w que dará la luminosidad adecuada. Si es demasiado igual los cambio por otros de 1w y 100mA de consumo, el driver me serviría igualmente (es una fuente de corriente).

Acabo de conseguir una FA averiada de un PC y ya he visto que trae 3 optos para probar, mañana suelto uno y prueba a ver si consigo que me mande via un BD437 +12v al led.
Ya me he pedido por ebay 5 PIC12F629 ya que no encontré mucha diferencia de precio respecto al 10F200 o 220 no recuerdo bien, que son los que vi en la lista de 'programables' por el winpic800. Tardarán un mes en llegar (China).

Mientras voy a ver si adapto el programita último que te dije que iba muy, pero muy bien. Al final dejé tiempo On 50mS, Off 1.5seg. y el antirrebortes a 100mS. Ya te digo, va de fábula sobre mi plaquita de pruebas: detecta rápidamente la pulsación de cualquier botón y de ambos a la vez. Estoy muy contento con el resultado.
No sé si con el Timer tendría alguna ventaja, igual si se queda dormido (sleep) y arranca al pulsar algún botón podría ser, pero como este tinglado funciona con la moto en marcha no me preocupa mucho unos mA porque el PIC esté en un bucle esperando una pulsación. Mientras no se rompa por ello, no me quita el sueño.

Voy a echar un ojo al enlace que me has dejado. Me supongo que adaptando las patillas VDD, VSS, CLK y las que intervengan en la programación del 16F84A al 12F629 debería poder ser programado. Voy a mirar a ver que se cuece.
Ya te contaré si funciona todo y queda listo para montar en la moto. La tarea mas chunga.

Saludos

Edito: Ya funciona con el optoacoplador, el led se ilumina perfectamente. Voy a adjuntar el esquema para el PIC16F84A con el que me ha funcionado por si a alguien le viene bien.

« Última modificación: 11 de Diciembre de 2010, 16:15:30 por ohsielos »

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Intermitentes moto.
« Respuesta #18 en: 13 de Diciembre de 2010, 08:56:40 »
Pues muy bueno el esquema, ademas le has puesto unos transistores que deben de ir sobrados, aislados con optos, mucho mejor que lo que deben de traer los de fabrica.
Te pongo el programa con TIMER, no es absolutamente necesario en este caso, pero es la manera mas normal de hacerlo. admas como veo que entiendes bien los programas que te he puesto, ya que sabes hacerles modificaciones, pues asi tambien aprendes de esta manera, aqui repito que no es totalmente necesario porque son solo dos pulsadores que los activan humanos, y somos muy lentos, simplemente haciendo chequeos cada 50ms es suficiente, pero hay ocasiones en que hay que controlar sensores electronicos muy rapidos y a veces muchos sensores, entonces hacer bucles de tiempo de 50ms es un tiempo enorme que el PIC no se entera de nada, de esta manera chequea continuamente los sensores, como mucho cada 15 millonesimas de segundo, ahora ya le puedes dejar la moto a Valentino Rossi que ni el tiene cojones a pulsarlo sin que se entere  :lol: :lol:.
Le he puesto un antirrebotes pequeño de 20ms, porque en el anterior no tenia en cuenta que cuando esta encendido un lado y se pulsa el contrario iba directamente, ahora ahi es donde hace ese antirrebotes para asegurarse.

Código: [Seleccionar]
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>

__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; oscilador XT

ERRORLEVEL -302

CBLOCK 0x0C

CONTADOR
CONTADOR_1
REG_1
PDel0
PDel1
PDel2
PDel3
 

 ENDC


#DEFINE LED_I PORTB,3
#DEFINE LED_D PORTB,4
#DEFINE PUL_I PORTA,2
#DEFINE PUL_D PORTA,1


ORG 0X00 ; VECTOR DE RESET
goto INICIO ; va a inicio
ORG 0x04 ; VECTOR DE INTERRUPCIONES



ORG 0X05
INICIO
bsf STATUS,5 ; activa la pagina 1
movlw 0XFF ; carga FF en W
movwf TRISA ; puerto A todos entradas aunque este puerto no se va a usar
movlw 0X00 ; carga 00000000 en W
movwf TRISB ; mueve W a puerto B (todos salidaS)
movlw 0X07 ; TIMER con preedcaler de 256, para 50ms
movwf OPTION_REG
movlw 0X20 ; habilitamos desborde de TIMER. pero sin interrupcion
movwf INTCON ; cada 50ms nos seteara el flag TOIF de INTCON
bcf STATUS,5 ; volvemos a la pagina 0
clrf PORTB ; ponemos a cero el puerto B para empezar con
; todos los LEDs apagados

clrf CONTADOR
clrf CONTADOR
clrf REG_1






ESPERA

btfss   PUL_I   
goto    $+3 ; va tres posiciones para delante
call      ANTIRREBOTES
goto     MAIN
btfss    PUL_D
goto     ESPERA
call      ANTIRREBOTES
goto    MAIN

TABLA          ;esta tabla nos dira que hay que hacer
addwf   PCL,1
goto     ESPERA  ; aqui nunc vendra, pero por si acaso....
goto     DERECHA
goto     IZQUIERDA
goto     LOS_DOS


MAIN

btfss   PUL_D    ; miramos si en PUL_D hay un 1 o un 0
bcf     REG_1,0  ; y escribimos en un registro lo que haya
btfsc   PUL_D    ; en el bit 0
bsf      REG_1,0
btfss   PUL_I     ; hacemos lo mismo con el otro pulsador
bcf      REG_1,1  ;este lo escribimos en el bit 1
btfsc   PUL_I
bsf      REG_1,1  ; aqui ya tenemos los dos pulsadores leidos y anotados en un registro
movf  REG_1,0    ; lo movemos a W
call    TABLA
goto   ESPERA

CAMBIA_I ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
; y haga algo indeseado
call ANTIRREBOTES_1
btfss PUL_I ; comprueba que realmente se pulso
goto ENCIENDE_D ; falsa alarma va a donde estaba
btfsc PUL_D ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia


IZQUIERDA

btfsc PUL_I ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto    ENCIENDE_I


DESACTIVAR_I

bcf     LED_I
clrf CONTADOR
btfsc PUL_I    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
return            ; apaga flag e intermitente y vueleve a MAIN, FLAG estaba a 1



ENCIENDE_I
bsf    LED_I    ; enciende intermitente izquierda
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto CAMBIA_D  ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto DESACTIVAR_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_I
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_I

bcf    LED_I    ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D   ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_D
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_I
clrf CONTADOR_1 ; ponemos a 0 contador

incf  CONTADOR,1  ; para numero de veces que encendera
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf  CONTADOR,0
btfss  STATUS,Z  ; van 10 veces?
goto  ENCIENDE_I    ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_I


CAMBIA_D ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
; y haga algo indeseado
call ANTIRREBOTES_1
btfss PUL_D ; comprueba que realmente se pulso
goto ENCIENDE_I ; falsa alarma va a donde estaba
btfsc PUL_I ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia


DERECHA

btfsc PUL_D ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_D

DESACTIVAR_D


bcf LED_D
clrf CONTADOR
btfsc PUL_D    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
return          ; apaga flag e intermitente y vuelve a MAIN; FLAG estaba a 1
 


ENCIENDE_D

bsf LED_D      ; enciende intermitente
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_D
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_D

bcf LED_D      ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2     ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_D
clrf CONTADOR_1 ; ponemos a 0 contador

incf CONTADOR,1  ; para número de veces que encenderá
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf CONTADOR,0
btfss STATUS,Z    ; van 10 veces?
goto ENCIENDE_D ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_D


LOS_DOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
clrf CONTADOR_1
bcf INTCON,2
goto   ENCIENDE_LOSDOS


DESACTIVAR_LOSDOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
clrf PORTB   ; apagamos intermitentes
return


ENCIENDE_LOSDOS

movlw  0x18
movwf PORTB  ; ponemos a 1 bits 3 y 4 del puerto B
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_I
goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2     ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_LOSDOS

clrf    PORTB  ; lo hago asi porque supongo que no tienes mas cosas coectadas en PORTB
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc  PUL_I
goto  DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador
goto    ENCIENDE_LOSDOS


ANTIRREBOTES               ;

DEMORA  movlw     .110      ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .181      ; 1 set numero de repeticion  (A)
        movwf     PDel1     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        clrwdt              ; 1 ciclo delay
        decfsz    PDel1, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  goto PDelL3         ; 2 ciclos delay
PDelL3  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


ANTIRREBOTES_1 ; antirrebotes de 20ms solo cuando esta funcionando un
; y se cambia para el otro, sin pasar por MAIN
movlw     .21       ; 1 set numero de repeticion  (B)
        movwf     PDel2     ; 1 |
PLoop3  movlw     .237      ; 1 set numero de repeticion  (A)
        movwf     PDel3     ; 1 |
PLoop4  clrwdt              ; 1 clear watchdog
        decfsz    PDel3, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop4    ; 2 no, loop
        decfsz    PDel2,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop3    ; 2 no, loop
PDelL4  goto PDelL5         ; 2 ciclos delay
PDelL5  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


END


Por otro lado si te preocupa el consumo de los intermitentes cuando la moto esta parada y tiene los cuatro puestos, porque lleva dos delante y dos detras no? o solo los de atras?, bueno podriamos ponerlos en bajo consumo, haciendo PWM y haciendo que se apagaran y encendieran muy rapido, se verian encendidos con menos brillo pero consumirian menos, para ello no tendrias que cambiar nada en el esquema solo hariamos unos cambios en el programa y listo.
Se podria hacer que cuando la dejes aparcada durante los primeros minutos esten a tope, y al pasar ese tiempo se pongan en bajo consumo, o que si pulsas los dos una pulsacion corta enciendan a tope ( porque si vas andando y hay un accidente y paras, poder indicarles a los que vienen atras que paras ) y si es para aparcar y la vas a dejar bastante tiempo, le pulsas un poco mas de tiempo 2s, por ejemplo y enciendan en bajo consumo, bueno tu eres el que sabes de motos ya me diras si te parece que podria ser util.
Ya estoy mirando el datasheet de 12f629, no lo programe nunca pero creo que no habra mucho problema, solo tengo unas dudas con el clock interno pero creo que las dare resuelto.

Saludos Tapi

Desconectado ohsielos

  • PIC10
  • *
  • Mensajes: 21
Re: Intermitentes moto.
« Respuesta #19 en: 13 de Diciembre de 2010, 13:02:53 »
Hola Tapi8.
Vaya currada con los timer. Lo he probado y va muy bien, le he cambiado en antirrebotes_1 de 20ms a 30 ya que el cambio directo de un intermitente que está funcionando al otro parece que va un poco mejor. Al igual que en el programa anterior (sin timer) la mayoría de las veces no cambia si no que hay que pulsar dos veces (una para parar la intermitencia del que está en marcha y otra para arrancar el intermitente contrario), casi siempre cuesta mas el paso de parpadeo izquierdo al derecho que al revés. Pero vamos, que no es un problema que me quite el sueño, me da igual si tengo que pulsar dos veces, el único pequeño inconveniente que pueda tener circulando es que hay que echarle un ojo a ver si van o no.

El tema de bajar el consumo con ambos en marcha: no pierdas el tiempo, en mi caso en parado lo he usado poquísimas veces, en marcha mas veces cuando salgo con muchos colegas. Es una Harley y hay veces que vamos a alguna concentración, y ahí a veces los pongo. De todas formas los 4 leds funcionando a la vez a 700mA serían 2.8A x50mS cada segundo y medio aprox. Con las 4 bombillas de 21w--->1.75Ax4= 7Ax200mS aprox. es mucho mas consumo.

Mi moto con la de V.Rossi no tiene muchos puntos comunes  :lol: Nosotros vamos en otra onda, lo nuestro es el relax y la contemplación  :D

Una duda que me asalta (entre muchísimas otras) y no le veo lógica son estas líneas seguidas:

24.- ORG 0X00        ; VECTOR DE RESET
25.- goto INICIO     ; va a inicio
26.- ORG 0x04        ; VECTOR DE INTERRUPCIONES
.
.
30.- ORG 0X05

Entiendo que la primera línea decimos que arrancamos la memoria en 0x00, supongo que una vez se va a INICIO ya no vuelve, y aunque volviera le diría que apunte a la posición 0x04 y acto seguido a la 0x05. No sé son cosas que me cogen muy mayor y se me descuadran, para que le digo que vaya a la 4 si después le digo que no, que a la 5??

Pasando a otro tema. Probé a adaptar el programita que funcionaba (sin timer) al 12F629, lo simulé y no me dió error. Los leds se encendían y apagaban bien con el PIC Simulator Ide. Me copié la forma de programarlo de algunos compañeros del foro. Solo me falta, en cuanto me lleguen los pics, a programarlo tal como me dejaste en el enlace para poder programarlo con el TE20 (es lo que imaginaba, poner las patas adecuadas en los pines correctos del programador). Te lo dejo para que lo veas:

Código: ASM
  1. __CONFIG _CP_OFF& _WDT_OFF&_PWRTE_ON&_BODEN_OFF&_INTRC_OSC_NOCLKOUT&_MCLRE_OFF 
  2.                
  3.         LIST    P=12F629
  4.         INCLUDE <P12F629.INC>
  5.        
  6.         errorlevel  -302
  7.        
  8.         CBLOCK 0x20
  9.         CONTADOR
  10.         CONTADOR_1
  11.         PDel0
  12.         PDel1
  13.         PDel2
  14.         PDel3
  15.         PDel4
  16.         REG_1
  17.         FLAG
  18.          ENDC
  19.  
  20.  
  21. #DEFINE LED_I GPIO,4
  22. #DEFINE LED_D GPIO,1
  23. #DEFINE PUL_I GPIO,5
  24. #DEFINE PUL_D GPIO,0
  25.        
  26.         ORG     h'0000'         ; VECTOR DE RESET
  27.         goto    INICIO          ; va a inicio
  28.         ORG     h'0004'         ; VECTOR DE INTERRUPCIONES
  29.  
  30.  
  31.  
  32.         ORG     H'0005'
  33. INICIO
  34.         clrf    GPIO
  35.         movlw   07h
  36.         movwf   CMCON           ; todos los pines en modo digital.
  37.         bsf     STATUS,5        ; activa banco 1
  38.         movlw   b'11101101'     ; GP0, 2, 3 y 5 entradas, GP1 y 4 salidas.
  39.         movwf   GPIO            ; puerto A todos entradas aunque este puerto no se va a usar
  40.         call    CALIBRAOSC
  41.         movwf   OSCCAL
  42.         clrf    INTCON          ; deshabilitar interrupciones.
  43.         bcf     STATUS,5
  44.         clrf    GPIO            ; volver al banco 0.           
  45.                                
  46.         clrf    CONTADOR
  47.         clrf    FLAG
  48.  
  49. ESPERA                          ; Leemos los pulsadores.
  50.         btfss   PUL_I           ; si está pulsado Izq. va a ANTIRREBOTES, si no
  51.         goto    $+3             ; va tres posiciones para adelante
  52.         call    ANTIRREBOTES    ; al volver de Antirrebotes se va a MAIN
  53.         goto    MAIN
  54.         btfss   PUL_D           ; si está pulsado va a ANTIRREBOTES, si no
  55.         goto    ESPERA          ; vuelve a leer los pulsadores.
  56.         call    ANTIRREBOTES    ; al volver de Antirrebotes se va a MAIN
  57.         goto    MAIN
  58.  
  59. TABLA                           ;esta tabla nos dirá que hay que hacer
  60.         addwf   PCL,1
  61.         goto    ESPERA          ; aquí nunca vendrá, pero por si acaso....
  62.         goto    DERECHA
  63.         goto    IZQUIERDA
  64.         goto    LOS_DOS
  65.  
  66.  
  67. MAIN
  68.         btfss   PUL_D           ; miramos si en PUL_D hay un 1 o un 0
  69.         bcf     REG_1,0         ; y escribimos en un registro lo que haya
  70.         btfsc   PUL_D           ; en el bit 0
  71.         bsf     REG_1,0
  72.         btfss   PUL_I           ; hacemos lo mismo con el otro pulsador
  73.         bcf     REG_1,1         ; éste lo escribimos en el bit 1
  74.         btfsc   PUL_I
  75.         bsf     REG_1,1         ; aquí ya tenemos los dos pulsadores leidos y anotados en un registro
  76.         movf    REG_1,0         ; lo movemos a W
  77.         call    TABLA
  78.         goto    ESPERA
  79.  
  80.  
  81. IZQUIERDA
  82.         btfsc   PUL_I           ; Aquí espera hasta que se suelte pulsador
  83.         goto    $-1             ; va una posición para atrás
  84.         clrf    CONTADOR
  85.         btfss   FLAG,0          ; miramos si hay un 1 en el Flag,0
  86.         goto    ACTIVAR_I       ; si no lo hay nos vamos a activar parpadeo Izq.
  87.        
  88.  
  89. DESACTIVAR_I   
  90.         bcf     FLAG,0
  91.         bcf     LED_I
  92.         clrf    CONTADOR
  93.         btfsc   PUL_I           ; espera hasta que se suelte pulsador
  94.         goto    $-1             ; porque si retornara sin esperar volvería a secuencia
  95.         return                  ; apaga flag e intermitente y vuelve a MAIN, FLAG estaba a 1
  96.  
  97.  
  98. ACTIVAR_I
  99.         bsf     FLAG,0          ; ponemos un 1 en el Flag,0
  100.         btfsc   PUL_I           ; salta si no está pulsado el Izq.
  101.         goto    DESACTIVAR_I    ; si mientras está ejecutando una secuencia
  102.                                 ; se pulsa un botón empieza de nuevo
  103.         btfsc   PUL_D           ; salta si no está pulsado el Dcho.
  104.         goto    DERECHA         ; si lo estuviese nos vamos a encender Dcho.
  105.  
  106. ENCIENDE_I
  107.         bsf     LED_I           ; enciende intermitente Izq.
  108.         call    DEMORA          ; está un tiempo encendido
  109.         btfsc   PUL_D           ; salta si no está pulsado el Dcho.
  110.         goto    DESACTIVAR_I    ; si mientras esta ejecutando una secuencia
  111.                                 ; se pulsa un botón empieza de nuevo
  112.         btfsc   PUL_I           ; salta si no está pulsado el Izq.
  113.         goto    IZQUIERDA       ; si lo estuviese nos vamos a encender Izq.
  114. ;       incf    CONTADOR_1,1   
  115. ;       movlw   .5              ; número de veces que se repite el retardo de 50ms
  116. ;       subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  117. ;       btfss   STATUS,Z        ; salta si el bit Z de Status es 1.
  118. ;       goto    ENCIENDE_I
  119.         clrf    CONTADOR_1      ; ponemos a 0 contador y nos vamos a apagar el led.
  120.  
  121. APAGA_I
  122.         bcf     LED_I           ; apaga el led Izq.
  123.         call    DEMORA          ; lo mantiene apagado 50ms.
  124.         btfsc   PUL_D           ; salta si no está pulsado el Dcho.
  125.         goto    DESACTIVAR_I    ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  126.         btfsc   PUL_I           ; salta si no está pulsado el Izq.
  127.         goto    IZQUIERDA       ; si lo está nos vamos a
  128.         incf    CONTADOR_1,1
  129.         movlw   .30             ; número de veces que se repite el retardo de 50ms
  130.         subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  131.         btfss   STATUS,Z
  132.         goto    APAGA_I
  133.         clrf    CONTADOR_1      ; ponemos a 0 contador
  134.        
  135.         incf    CONTADOR,1      ; para número de veces que encenderá
  136.         movlw   .10             ; le pongo 10 pero pueden ser las que tu quieras
  137.         subwf   CONTADOR,0
  138.         btfss   STATUS,Z        ; van 10 veces?
  139.         goto    ACTIVAR_I       ; no, vuelve a repetir secuencia
  140.         clrf    CONTADOR       
  141.         goto    DESACTIVAR_I
  142.  
  143. DERECHA
  144.         btfsc   PUL_D           ; Aquí espera hasta que se suelte pulsador
  145.         goto    $-1             ; va una posición para atrás
  146.         clrf    CONTADOR
  147.         btfss   FLAG,1
  148.         goto    ACTIVAR_D
  149.        
  150. DESACTIVAR_D   
  151.         bcf     FLAG,1          ; pone un 0 en el bit 1 de Flag.
  152.         bcf     LED_D           ; apaga led Dcho.
  153.         clrf    CONTADOR        ; pone a 0 el Contador.
  154.         btfsc   PUL_D           ; espera hasta que se suelte pulsador
  155.         goto    $-1             ; porque si retornara sin esperar volvería a secuencia
  156.         return                  ; apaga flag e intermitente y vuelve a MAIN; FLAG estaba a 1
  157.  
  158. ACTIVAR_D
  159.         bsf     FLAG,1
  160.         btfsc   PUL_D           ; salta si no está pulsado el Dcho.
  161.         goto    DESACTIVAR_D    ; si mientras esta ejecutando una secuencia
  162.                                 ; se pulsa un botón empieza de nuevo
  163.         btfsc   PUL_I           ; salta si no está pulsado el Izq.
  164.         goto    IZQUIERDA
  165.        
  166. ENCIENDE_D
  167.         bsf     LED_D           ; enciende intermitente Dcho.  
  168.         call    DEMORA          ; está un tiempo encendido
  169.         btfsc   PUL_D
  170.         goto    DESACTIVAR_D    ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  171.         btfsc   PUL_I
  172.         goto    IZQUIERDA
  173. ;       incf    CONTADOR_1,1
  174. ;       movlw   .50             ; número de veces que se repite el retardo de 50ms
  175. ;       subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  176. ;       btfss   STATUS,Z
  177. ;       goto    ENCIENDE_D
  178.         clrf    CONTADOR_1      ; ponemos a 0 contador
  179.  
  180. APAGA_D
  181.         bcf     LED_D           ; apaga
  182.         call    DEMORA
  183.         btfsc   PUL_D
  184.         goto    DESACTIVAR_D    ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  185.         btfsc   PUL_I
  186.         goto    IZQUIERDA
  187.         incf    CONTADOR_1,1
  188.         movlw   .30             ; número de veces que se repite el retardo de 50ms
  189.         subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  190.         btfss   STATUS,Z
  191.         goto    APAGA_D
  192.         clrf    CONTADOR_1      ; ponemos a 0 contador
  193.        
  194.         incf    CONTADOR,1      ; para número de veces que encenderá
  195.         movlw   .10             ; le pongo 10 pero pueden ser las que tu quieras
  196.         subwf   CONTADOR,0
  197.         btfss   STATUS,Z        ; van 10 veces?
  198.         goto    ACTIVAR_D       ; no, vuelve a repetir secuencia
  199.         clrf    CONTADOR
  200.         goto    DESACTIVAR_D
  201.  
  202.  
  203. LOS_DOS
  204.         btfsc   PUL_I
  205.         goto    $-1
  206.         btfsc   PUL_D           ; miramos si están sin pulsar ambos botones
  207.         goto    $-3
  208.         btfss   FLAG,2          ; flag para saber si apagamos o encendemos
  209.         goto    ACTIVAR_LOSDOS
  210.  
  211. DESACTIVAR_LOSDOS
  212.         btfsc   PUL_I
  213.         goto    $-1
  214.         btfsc   PUL_D           ; miramos si están sin pulsar ambos botones
  215.         goto    $-3    
  216.         bcf     FLAG,2          ;apagamos intermitentes y borramos flag, ya que estaba a 1
  217.         clrf    GPIO            ; apagamos intermitentes
  218.        
  219.         return
  220.  
  221. ACTIVAR_LOSDOS
  222.         bsf     FLAG,2          ; el flag estaba a 0 lo activamos
  223.         btfsc   PUL_I
  224.         goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  225.         btfsc   PUL_D
  226.         goto    DESACTIVAR_LOSDOS
  227.         movlw   0x18
  228.         movwf   GPIO            ; ponemos a 1 bits 3 y 4 del puerto B
  229.        
  230. ENCIENDE_LOSDOS
  231.         call    DEMORA          ; tiempo encendidos
  232.         btfsc   PUL_I
  233.         goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  234.         btfsc   PUL_D
  235.         goto    DESACTIVAR_LOSDOS
  236. ;       incf    CONTADOR_1,1
  237. ;       movlw   .50             ; número de veces que se repite el retardo de 50ms
  238. ;       subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  239. ;       btfss   STATUS,Z
  240. ;       goto    ENCIENDE_LOSDOS
  241.         clrf    CONTADOR_1      ; ponemos a 0 contador
  242.  
  243. APAGA_LOSDOS           
  244.         clrf    GPIO            ; lo hago así porque supongo que no tienes mas cosas coectadas en PORTB
  245.         call    DEMORA
  246.         btfsc   PUL_I
  247.         goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  248.         btfsc   PUL_D
  249.         goto    DESACTIVAR_LOSDOS
  250.         incf    CONTADOR_1,1
  251.         movlw   .30             ; número de veces que se repite el retardo de 50ms
  252.         subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  253.         btfss   STATUS,Z
  254.         goto    APAGA_LOSDOS
  255.         clrf    CONTADOR_1      ; ponemos a 0 contador
  256.         goto    ACTIVAR_LOSDOS
  257.  
  258.  
  259.  
  260. ANTIRREBOTES                
  261.                                 ; 100ms, aparte de servir de antirrebotes, también compensará                         ; si no se pulsan exactamente al mismo tiempo los dos botones
  262.         movlw   .110            ; 1 set número de repetición  (B)
  263.        movwf    PDel2           ; 1 |
  264. PLoop3  movlw   .181            ; 1 set número de repetición  (A)
  265.         movwf   PDel3           ; 1 |
  266. PLoop4  
  267. ;       clrwdt                  ; 1 clear watchdog
  268. PDelL8  goto    PDelL9          ; 2 ciclos delay
  269. PDelL9  goto    PDelL10         ; 2 ciclos delay
  270. PDelL10  
  271.         decfsz  PDel3,1         ; 1 + (1) es el tiempo 0  ? (A)
  272.         goto    PLoop4          ; 2 no, loop
  273.         decfsz  PDel2,1         ; 1 + (1) es el tiempo 0  ? (B)
  274.         goto    PLoop3          ; 2 no, loop
  275. PDelL11  goto   PDelL12                 ; 2 ciclos delay
  276. PDelL12  
  277. ;       clrwdt                  ; 1 ciclo delay
  278.         return                  ; 2+2 Fin.
  279. ;-----------------------------------------------
  280.  
  281.  
  282.  
  283. DEMORA                          ; retardo de 50ms que se repetirá las veces que sea necesario
  284.                                 ; para completar el tiempo adecuado para las intermitencias
  285.         movlw   .55             ; 1 set número de repetición  (B)
  286.         movwf   PDel0           ; 1 |
  287. PLoop1  movlw   .181            ; 1 set número de repetición  (A)
  288.         movwf   PDel1           ; 1 |
  289. PLoop2  
  290. ;       clrwdt                  ; 1 clear watchdog
  291. ;        clrwdt                 ; 1 ciclo delay
  292.         decfsz  PDel1, 1        ; 1 + (1) es el tiempo 0  ? (A)
  293.         goto    PLoop2          ; 2 no, loop
  294.         decfsz  PDel0,  1       ; 1 + (1) es el tiempo 0  ? (B)
  295.         goto    PLoop1          ; 2 no, loop
  296.         return                  ; 2+2 Fin.
  297.        
  298.         org     0x3FF
  299.        
  300. CALIBRAOSC      retlw   0x80    ;calibro oscilador a 4 mhz +- 2%        
  301.        
  302.        
  303.         END

De nuevo, muchas gracias Tapi8.
Voy a ver si 'capto' el funcionamiento del timer.

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Intermitentes moto.
« Respuesta #20 en: 15 de Diciembre de 2010, 06:59:01 »
Bueno lo que comentas de:

24.- ORG 0X00        ; VECTOR DE RESET
25.- goto INICIO     ; va a inicio
26.- ORG 0x04        ; VECTOR DE INTERRUPCIONES
.
.
30.- ORG 0X05
       INICIO

0x00 es donde el PIC empieza a hacer andar el programa es una direccion que el tiene ahi y es a donde va por hardware cuando se produce un reset por baja tension, watch dog, etc. Despues tiene la 0x04 que es otra posiscion, aqui es a donde va cuando se produce una interrupcion, y bien se hace ahi la rutina de interrupcion o bien mediante un goto se envia a la etiqueta donde esta ubicada la interrupcion, el objeto de ese goto inicio es para saltar ese vector de interrupcion y que vaya a 0x05 que empieza el programa.

Yo penesando que estaba haciendo los intermitentes de un vespino y resulta que nada menos que una HARLEY, QUE BUENO :-/ :-/

Es cierto que tenia unos fallos en los cambios de una intermitencia a la otra, y mas en el cambio de izquierda a derecha, los he corregido, o eso creo, prueba este:


Código: [Seleccionar]
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>

__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; oscilador XT

ERRORLEVEL -302

CBLOCK 0x0C

CONTADOR
CONTADOR_1
REG_1
PDel0
PDel1
PDel2
PDel3
 

 ENDC


#DEFINE LED_I PORTB,3
#DEFINE LED_D PORTB,4
#DEFINE PUL_I PORTA,2
#DEFINE PUL_D PORTA,1


ORG 0X00 ; VECTOR DE RESET
goto INICIO ; va a inicio
ORG 0x04 ; VECTOR DE INTERRUPCIONES



ORG 0X05
INICIO
bsf STATUS,5 ; activa la pagina 1
movlw 0XFF ; carga FF en W
movwf TRISA ; puerto A todos entradas aunque este puerto no se va a usar
movlw 0X00 ; carga 00000000 en W
movwf TRISB ; mueve W a puerto B (todos salidaS)
movlw 0X07 ; TIMER con preedcaler de 256, para 50ms
movwf OPTION_REG
movlw 0X20 ; habilitamos desborde de TIMER. pero sin interrupcion
movwf INTCON ; cada 50ms nos seteara el flag TOIF de INTCON
bcf STATUS,5 ; volvemos a la pagina 0
clrf PORTB ; ponemos a cero el puerto B para empezar con
; todos los LEDs apagados

clrf CONTADOR
clrf CONTADOR
clrf REG_1






ESPERA

btfss   PUL_I   
goto    $+3 ; va tres posiciones para delante
call      ANTIRREBOTES
goto     MAIN
btfss    PUL_D
goto     ESPERA
call      ANTIRREBOTES
goto    MAIN

TABLA          ;esta tabla nos dira que hay que hacer
addwf   PCL,1
goto     ESPERA  ; aqui nunc vendra, pero por si acaso....
goto     DERECHA
goto     IZQUIERDA
goto     LOS_DOS


MAIN

btfss   PUL_D    ; miramos si en PUL_D hay un 1 o un 0
bcf     REG_1,0  ; y escribimos en un registro lo que haya
btfsc   PUL_D    ; en el bit 0
bsf      REG_1,0
btfss   PUL_I     ; hacemos lo mismo con el otro pulsador
bcf      REG_1,1  ;este lo escribimos en el bit 1
btfsc   PUL_I
bsf      REG_1,1  ; aqui ya tenemos los dos pulsadores leidos y anotados en un registro
movf  REG_1,0    ; lo movemos a W
call    TABLA
goto   ESPERA

CAMBIA_I ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
bcf LED_D
call ANTIRREBOTES_1
btfss PUL_I ; comprueba que realmente se pulso
goto ENCIENDE_D ; falsa alarma va a donde estaba
btfsc PUL_D ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia


IZQUIERDA

btfsc PUL_I ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto    ENCIENDE_I


DESACTIVAR_I

bcf     LED_I
clrf CONTADOR
btfsc PUL_I    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
return            ; apaga flag e intermitente y vueleve a MAIN, FLAG estaba a 1



ENCIENDE_I
bsf    LED_I    ; enciende intermitente izquierda
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto CAMBIA_D  ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto DESACTIVAR_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_I
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_I

bcf    LED_I    ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto CAMBIA_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto DESACTIVAR_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_I
clrf CONTADOR_1 ; ponemos a 0 contador

incf  CONTADOR,1  ; para numero de veces que encendera
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf  CONTADOR,0
btfss  STATUS,Z  ; van 10 veces?
goto  ENCIENDE_I    ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_I


CAMBIA_D ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
bcf LED_I ;
call ANTIRREBOTES_1
btfss PUL_D ; comprueba que realmente se pulso
goto ENCIENDE_I ; falsa alarma va a donde estaba
btfsc PUL_I ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia


DERECHA

btfsc PUL_D ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_D

DESACTIVAR_D


bcf LED_D
clrf CONTADOR
btfsc PUL_D    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
return          ; apaga flag e intermitente y vuelve a MAIN; FLAG estaba a 1
 


ENCIENDE_D

bsf LED_D      ; enciende intermitente
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_D
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_D

bcf LED_D      ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_D
clrf CONTADOR_1 ; ponemos a 0 contador

incf CONTADOR,1  ; para número de veces que encenderá
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf CONTADOR,0
btfss STATUS,Z    ; van 10 veces?
goto ENCIENDE_D ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_D


LOS_DOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
clrf CONTADOR_1
bcf INTCON,2
goto    ENCIENDE_LOSDOS


DESACTIVAR_LOSDOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
clrf PORTB    ; apagamos intermitentes
return


ENCIENDE_LOSDOS

movlw  0x18
movwf PORTB  ; ponemos a 1 bits 3 y 4 del puerto B
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_I
goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_LOSDOS

clrf    PORTB  ; lo hago asi porque supongo que no tienes mas cosas coectadas en PORTB
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc  PUL_I
goto  DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador
goto    ENCIENDE_LOSDOS


ANTIRREBOTES               ;

DEMORA  movlw     .110      ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .181      ; 1 set numero de repeticion  (A)
        movwf     PDel1     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        clrwdt              ; 1 ciclo delay
        decfsz    PDel1,1   ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel0,1   ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  goto PDelL3         ; 2 ciclos delay
PDelL3  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


ANTIRREBOTES_1 ; antirrebotes de 20ms solo cuando esta funcionando un
; y se cambia para el otro, sin pasar por MAIN
movlw     .21       ; 1 set numero de repeticion  (B)
        movwf     PDel2     ; 1 |
PLoop3  movlw     .237      ; 1 set numero de repeticion  (A)
        movwf     PDel3     ; 1 |
PLoop4  clrwdt              ; 1 clear watchdog
        decfsz    PDel3,1   ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop4    ; 2 no, loop
        decfsz    PDel2,1   ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop3    ; 2 no, loop
PDelL4  goto PDelL5         ; 2 ciclos delay
PDelL5  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


END

La duda que tenia con el 16f629 era la calibracion, pero ya he visto como va, en el datashheet en ingles no estaba totalmente seguro pero si ya es asi, listo.

Desconectado ohsielos

  • PIC10
  • *
  • Mensajes: 21
Re: Intermitentes moto.
« Respuesta #21 en: 17 de Diciembre de 2010, 13:59:53 »
Hola de nuevo, Tapi8.

Llevo unos días probando y modificando/quitando los tiempos de antirrebotes, añadiendo alguna línea para ver si consigo mejorar la respuesta al cambio de un pulsador al otro mientras parpadea.

Te cuento el fallo que le veo, que en última instancia paso del cambio mientras parpadea, es éste: mientras entá parpadeando cualquiera de los dos si hago el cambio al que está apagado, a veces (75%) no lo hace, se quedan ambos apagados; en esos casos (cuando he intentado pasar de uno al otro sin terminar el ciclo del que parpadeaba), para que arranque el que quería que funcionara he de pulsar 2, 3 o 4 veces porque no arranca. Sin embargo como va bien casi al 100% es apagando el que parpadea y arrancando el otro; digo 'casi' porque en un porcentaje muy pequeño no arranca y he de pulsar varias veces.

He revisado el programa y lo veo perfecto. Las llamadas a los cambios de intermitentes o a los apagados y todo parece estar bien. La parte que no domino nada es la de los timer's. No sé si alguno se queda funcionando al cambiar de intermitente y arranca otro y ahí se produce el bloqueo. O igual es mi pic que lleva tropecientos mil borrados y regrabados. Por aquí tengo también un PIC16F628A, que no sé si ponerme con él o esperar a que me lleguen los 12F629 para trabajar con los definitivos.

De todas formas como te digo, podría pasar del tema de los cambios directos del uno al otro y pasar a apagar uno y arrancar el otro. Es cuestión de acostumbrarse, y tampoco me suelo equivocar tanto cuando voy circulando.

Me alegro que te mole mi hierro, la tengo hace 15 años y está como nueva. En cuanto tenga todo listo haré unas fotos y las colgaré con un mini tutorial del montaje e instalación en el foro de motos en el que también participo para compartirlo con los compañeros. Te dejaré un enlace para que tú también lo veas. Y si puedo colgaré un video con el antes y después de la transformación. Pero eso tardará un poco, ya que no dispongo de local para trabajar con tiempo; he de hacerlo todo en el día y en la calle. Es lo que mas me cuesta.

Bueno, sigo con las pruebas. Gracias de nuevo por tu interés.

Un saludo.

Desconectado juan47

  • PIC10
  • *
  • Mensajes: 27
Re: Intermitentes moto.
« Respuesta #22 en: 17 de Diciembre de 2010, 15:18:57 »
Hola
Yo, como Tapi8, tambien pensaba que seria para un ciclomotor, no para tanbuen hierro  :-/
e intervine por que mi hijo tiene un ciclomotor y asi poder tambien montarselo   :oops:
Bueno al tema, no he tenido mucho tiempo para poder estar pendiente, y Tapi8 ha efectuado un trabajo genial
aunque en tu ultimo post comentas que la respuesta no es lo que esperabas
Pongo un codigo que he escrito pero no he podido probarlo fisicamente pues la falta de tiempo y el no poder concentrarse
me ha sido imposible construirlo. Pero si lo he provado con un proteus de un amigo y el funcionamiento es el correcto
pero para pasar de un led a otro es obvio que hay que pulsar dos veces el pulsador
uno para apagar el que ya esta encendido y otra para encender el que deseamos

Código: ASM
  1. LIST                    P=16F84A
  2.                                        
  3. W       EQU                     0x00
  4. F       EQU                     0x01
  5. TMR0    EQU                     0x01
  6. ESTADO  EQU                     0x03
  7. RP0     EQU                     0x05
  8. INTCON  EQU                     0x0B
  9. TOIF    EQU                     0x02
  10. GIE     EQU                     0x07
  11. RBIE    EQU                     0x03
  12. RBIF    EQU                     0x00
  13. PUERTAA EQU                     0x05
  14. PUERTAB EQU                     0x06
  15. OPTIO   EQU                     0X81
  16. TRISA   EQU                     0x85
  17. TRISB   EQU                     0x86
  18. REG_1   EQU                     0x0C
  19. REG_2   EQU                     0x0D
  20. CONT_1  EQU                     0x0E
  21. CONT_2  EQU                     0x0F
  22.  
  23.                                                 org             0x00                    ;Vector de inicio
  24.                                                 GOTO    INICIO                          ;Va a la etiqueta inicio                                               
  25.                                                 org             0x04                    ;Vector de interrupcion
  26.                                                 CALL    INT                             ;Llama a la subrutina de interrupcion
  27.                                                
  28.                                                 org             0x05
  29.  
  30.                                                
  31. INICIO                  bsf             INTCON,GIE                                      ;Permiso general de interrupciones
  32.                                 bsf             INTCON,RBIE                                     ;Permiso de interrupcion porRB4-RB7
  33.                                 bsf             ESTADO,RP0                                      ;Pasa al banco 1
  34.                                 movlw   b'10000111'                                     ;Preescaler para TMR0
  35.                                 movwf   OPTIO                                          
  36.                                 movlw   b'01100000'                                     ;RB6,RB5 entradas, resto salidas                               
  37.                                 movwf   TRISB
  38.                                 bcf             ESTADO,RP0                                      ;Pasa al banco 0
  39. DUERME                  clrf    PUERTAB                                         ;Pone a cero el puerto B
  40.                                 clrf    REG_1                                           ;Pone a cero el registro REG_1
  41.                                 sleep                                                           ;Duerme
  42.  
  43.                                
  44. INT                             btfsc   REG_1,1                                         ;¿Es cero el bit 1?
  45.                                 goto    DUERME                                          ;No.Resetea el registro REG_1
  46.                                 btfsc   REG_1,2                                         ;¿Es cero el bit 2?
  47.                                 goto    DUERME                                          ;No.Resetea el registro REG_1
  48.                                 goto    PRUEBA                                          ;Si
  49.                                                        
  50. PRUEBA                  bcf             INTCON,RBIF                                     ;Pone a 0 el flag de RB4-RB7
  51.                                 bsf             INTCON,GIE                                      ;Pone a 1 el permiso general de interrupcion
  52.                                 swapf   PUERTAB,F                                       ;Intercambio de los bits de mayor peso por los de menor peso
  53.                                 movf    PUERTAB,W                                       ;Efectua una mascara
  54.                                 andlw   b'00000110'                                     ;para borrar los bits de mas peso
  55.                                 subwf   REG_1,F                                         ;pasando al final al registro REG_1
  56.                                 movwf   REG_1
  57.  
  58. INTERMITENCIA   movlw   d'9'                                            ;Seran 9 las veces
  59.                                 movwf   CONT_2                                          ;que parpadee el led
  60. INTER                   movf    REG_1,W                                         ;Movemos los bits del regitro a W
  61.                                 movwf   PUERTAB                                         ;Movemos los bits de W al puerto B
  62.                                 call    ANTIRREBOTES                            ;Se llama al retardo
  63.                                 clrf    PUERTAB                                         ;Borramos el puerto B
  64.                                 call    ANTIRREBOTES                            ;Se llama al retardo
  65.                                 decfsz  CONT_2,F                                        ;Decrementamos el registro ¿y es 0?
  66.                                 call    INTER                                           ;No
  67.                                 goto    DUERME                                          ;Si.A dormir
  68.                                
  69.  
  70. ANTIRREBOTES    movlw   d'15'                                           ;Bucle externo que se repetira 15 veces
  71.                                 movwf   CONT_1
  72. BUCLE1                  movlw   0x00                                            ; Inicializacion del bucle interno
  73.                                 movwf   TMR0
  74. BUCLE2                  btfss   INTCON,TOIF                                     ;Ha terminado de contar?
  75.                                 goto    BUCLE2                                          ;No.Continua el bucle interno
  76.                                 bcf             INTCON,TOIF                                     ;Si.Baja bandera
  77.                                 decfsz  CONT_1,F                                        ;decrementar contador del bucle externo
  78.                                 goto    BUCLE1                                          ;Como no llega a 0, vlver a hacer el bucle interno
  79.                                 return                                                          ;Al llegar a 0 el contador externo volver a la rutina
  80.  
  81.  
  82.                                 END
Un saludo

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Intermitentes moto.
« Respuesta #23 en: 17 de Diciembre de 2010, 15:33:26 »
Lo del video y las fotos molaria muchisimo, yo no ando en moto me acojonan mucho, pero soy un gran aficionado al motociclismo, pero verlo solamente, pero si alguna vez anduviera en una seria una Harley, me dan confianza.

Eso que te pasa es con este ultimo que te puse?, Poruqe si tenia unos fallos que le he corregido, con este que esta antes de tu ultimo post, he hecho muchas pruebas en MPLAB y no me falla nunca.

Puede que haya un problema con los rebotes al soltar el pulsador, porque no lo he contemplado y seguramente haya tantos rebotes al soltar como al pulsar, pero el porcentaje de fallos no deberia ser tan alto, o eso creo.

Lo solucionaremos no te preocupes, el fin de semana te cuelgo otro con los antirrebotes al soltar y vemos que pasa.

Desconectado ohsielos

  • PIC10
  • *
  • Mensajes: 21
Re: Intermitentes moto.
« Respuesta #24 en: 17 de Diciembre de 2010, 19:25:18 »
Hola.
   Tapi8: gracias, la verdad que sí es una buena máquina, y mas allá de la calidad del acabado, lo que mas me engancha son las vibraciones que transmite, es realmente difícil de explicar. Sobre todo la mía que es de carburación y con el motor anclado directamente al chasis, los pistonazos los sientes físicamente en el cuerpo, esto se ha perdido un poco con las leyes anticontaminación que ha obligado a H-D usar la inyección. No sé, es algo que hay que probar. Antes de ésta tenía una Kawa 900 y no tiene nada que ver. Es lo que tu dices: dan confianza, los coches te respetan un poco más por el sonido y lo que imponen 350 kg.
No te preocupes que cuando suba el montaje lo posteo.

   El tema: este funcionamiento errático al cambiar de un intermitente al otro sin que se haya detenido el parpadeo es mas o menos igual en todos lo programas, hay veces que está funcionando bien durante los primeros 3 o 4 cambios y después es como si entrara en conflicto algo que bloquea el pulsador último al que quería ir y hasta que no le doy unas 4 veces no recupera el funcionamiento normal. Pero como te dije, puedo pasar y hacer los cambios cancelando el parpadeo del que está en marcha antes de ir al otro.

   Juan47: normalmente (por lo menos en mi ex-Kawa) los intermitentes los controlaba con la mano izquierda. Tenía un conmutador de 3 posiciones izq/centro/der has de asegurarte que cables llegan y si envían 12v o masa. en cuyo caso a las entradas del pic le pueden llegar tensión o masa cuando lo pulses. No creo que te haga falta el cambio directo de un intermitente al otro porque siempre pasa por el centro. En mi caso tengo un pulsador en cada puño y envía 12v al pulsarlo a una 'unidad de intermitencias' que es la que se encarga de lanzar los +12v del parpadeo a cada pareja de intermitentes. Además, y como curiosidad, esta unidad tiene una entrada que viene del ctakm y que por lo visto mientras la rueda gire está recibiendo pulsos, mas rápidos cuanto más rápido vaya, y entonces la 'unidad de intermitencias' regula el tiempo que está parpadeando: si estoy parado (no hay pulsos) nunca deja de parpadear, por ejemplo en una caravana intentando tomar una salida; y cuanto mas rápido voy menos dura el tiempo que está parpadeando (dentro de un límite, claro, nunca es muy corto, por lo menos 7 u 8 da). Pero yo he estimado que entre 9 y 12 parpadeos está mas que bien y evito liar el tema y que sea mas susceptible de dar errores.
No te preocupes que voy a probar también tu programa a ver que tal.
Como le dije a Tapi8, igual mi pobre 16F84A está hasta el gorro de mí y está pidiendo clemencia.
En cuanto lo pruebe y haga las modificaciones si algo no rula bien, te digo algo.

Solo comentar que las pruebas las hago con una plaquita con el pic, el cuarzo con 2 cond., el regulador para 5v, etc, como en el esquema que puse mas arriba, y lo alimento con una pila de 9v, porque montar la fuente del PC para sacar los +12v. es mucho mas engorroso para mí, que reprogramo cada 5-10 minutos. No creo que falle por ello. No sé....me he quedado con la duda.

Bueno, de nuevo gracias a todos. Me alegra que el tema vaya gustando a los compañeros. La verdad que los leds tienen muchas ventajas, sobre todo fiabilidad, bajo consumo, y potencia (en mi caso).

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Intermitentes moto.
« Respuesta #25 en: 20 de Diciembre de 2010, 07:51:35 »
Bueno pensaba poner el programa el fin de semana pero no tuve tiempo. Le he corregido alguna cosilla y sobre todo le he puesto antirrebotes para cuando se sueltan los pulsadores, te digo como va:
Cuando esta funcionando uno de los dos y se pulsa el contrario, en ese momento deja de funcionar el que estaba funcionando y AL SOLTAR EL PULSADOR, empieza a funcionar el contrario, el resto es igual que hasta ahora, cuando se pulsa uno de los dos o los dos a la vez hace la secuencia seleccionada al soltar el pulsador o los pulsadores.
Cuando estan los dos intermitentes puestos, basta con pulsar uno de los dos y al soltar apagan.
He probado muchisimas veces en el MPLAB y no falla nunca pero en la realidad a ver que pasa....
Ya tengo algun amigo por aqui motero que le pica la curiosidad por ver este invento. :lol: :lol:



Código: [Seleccionar]
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>

__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; oscilador XT

ERRORLEVEL -302

CBLOCK 0x20 ; ponemos 0x20 para que valga para todos
; incluido 12f629
CONTADOR
CONTADOR_1
REG_1
PDel0
PDel1
PDel2
PDel3
 

 ENDC


#DEFINE LED_I PORTB,3
#DEFINE LED_D PORTB,4
#DEFINE PUL_I PORTA,2
#DEFINE PUL_D PORTA,1


ORG 0X00 ; VECTOR DE RESET
goto INICIO ; va a inicio
ORG 0x04 ; VECTOR DE INTERRUPCION


INICIO
bsf STATUS,5 ; activa la pagina 1
movlw 0XFF ; carga FF en W
movwf TRISA ; puerto A todos entradas
movlw 0X00 ; carga 00000000 en W
movwf TRISB ; mueve W a puerto B (todos salidaS)
movlw 0X07 ; TIMER con preedcaler de 256, para 50ms
movwf OPTION_REG
movlw 0X20 ; habilitamos desborde de TIMER. pero sin interrupcion
movwf INTCON ; cada 50ms nos seteara el flag TOIF de INTCON
bcf STATUS,5 ; volvemos a la pagina 0
clrf PORTB ; ponemos a cero el puerto B para empezar con
;  los intermitentes apagados

clrf CONTADOR
clrf CONTADOR_1
clrf REG_1


ESPERA

btfss   PUL_I   
goto    $+3 ; va tres posiciones para delante
call      ANTIRREBOTES
goto     MAIN
btfss    PUL_D
goto     ESPERA
call      ANTIRREBOTES
goto    MAIN

TABLA          ;esta tabla nos dira que hay que hacer
addwf   PCL,1
goto     ESPERA  ; aqui nunc vendra, pero por si acaso....
goto     DERECHA
goto     IZQUIERDA
goto     LOS_DOS

MAIN

btfss   PUL_D    ; miramos si en PUL_D hay un 1 o un 0
bcf     REG_1,0  ; y escribimos en un registro lo que haya
btfsc   PUL_D    ; en el bit 0
bsf      REG_1,0
btfss   PUL_I     ; hacemos lo mismo con el otro pulsador
bcf      REG_1,1  ;este lo escribimos en el bit 1
btfsc   PUL_I
bsf      REG_1,1  ; aqui ya tenemos los dos pulsadores leidos y anotados en un registro
movf  REG_1,0    ; lo movemos a W
call    TABLA
goto   ESPERA

CAMBIA_I ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
bcf LED_D
call ANTIRREBOTES_1
btfss PUL_I ; comprueba que realmente se pulso
goto ENCIENDE_D ; falsa alarma va a donde estaba
btfsc PUL_I ; se espera hasta que se suelte
goto $-1
call ANTIRREBOTES_1 ; llama antirrebotes para confirmar
btfsc PUL_I ; se mira si de verdad se solto
return ; paso algo raro vuelve a MAIN
btfsc PUL_D ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_I


IZQUIERDA

btfsc PUL_I ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
call ANTIRREBOTES_1 ; para comprobar si hay rebotes al soltar
btfsc PUL_I ; se confirma que se solto pulsador
return ; falsa alarma va a MAIN
bcf INTCON,2 ; se solto y no hay rebotes
clrf CONTADOR ; pone contadores a 0 e inicia secuencia
clrf CONTADOR_1
goto    ENCIENDE_I


DESACTIVAR_I

bcf     LED_I
clrf CONTADOR
clrf CONTADOR_1
btfsc PUL_I    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
call ANTIRREBOTES_1
btfsc PUL_I ; despues de antirrebotes confirma se solto
goto $-4 ; fueron rebotes va a primer chequeo
return            ; apaga flag e intermitente y vueleve a MAIN, FLAG estaba a 1

ENCIENDE_I

bsf    LED_I    ; enciende intermitente izquierda
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto CAMBIA_D  ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto DESACTIVAR_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_I
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_I

bcf    LED_I    ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto CAMBIA_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto DESACTIVAR_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_I
clrf CONTADOR_1 ; ponemos a 0 contador

incf  CONTADOR,1  ; para numero de veces que encendera
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf  CONTADOR,0
btfss  STATUS,Z  ; van 10 veces?
goto  ENCIENDE_I    ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_I

CAMBIA_D ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
bcf LED_I ;
call ANTIRREBOTES_1
btfss PUL_D ; comprueba que realmente se pulso
goto ENCIENDE_I ; falsa alarma va a donde estaba
btfsc PUL_D ; se espera hasta que se suelte
goto $-1
call ANTIRREBOTES_1 ; llama antirrebotes para confirmar
btfsc PUL_D ; se mira si de verdad se solto
return ; paso algo raro vuelve a MAIN
btfsc PUL_I ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_D

DERECHA

btfsc PUL_D ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
call ANTIRREBOTES_1 ; para comprobar si hay rebotes al soltar
btfsc PUL_D ; se confirma que se solto pulsador
return ; falsa alarma va a MAIN
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_D

DESACTIVAR_D

bcf LED_D
clrf CONTADOR
clrf CONTADOR_1
btfsc PUL_D    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
call ANTIRREBOTES_1
btfsc PUL_D ; despues de antirrebotes confirma se solto
goto $-4 ; fueron rebotes va a primer chequeo
return          ; apaga intermitente y vuelve a MAIN
 
ENCIENDE_D

bsf LED_D      ; enciende intermitente
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_D
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_D

bcf LED_D      ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_D
clrf CONTADOR_1 ; ponemos a 0 contador

incf CONTADOR,1  ; para número de veces que encenderá
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf CONTADOR,0
btfss STATUS,Z    ; van 10 veces?
goto ENCIENDE_D ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_D

LOS_DOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
call ANTIRREBOTES_1
movf PORTA,0 ; movemos PORTA a W para comprobar que vale 0
btfss STATUS,Z ; encendio FLAG de 0?
goto LOS_DOS ; fueron rebotes vuelve a comprobar despulsacion
clrf CONTADOR
clrf CONTADOR_1
bcf INTCON,2
goto    ENCIENDE_LOSDOS

DESACTIVAR_LOSDOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
call ANTIRREBOTES_1
movf PORTA,0 ; para confirmar que se soltaron
btfss STATUS,Z ; comprobamos que el valor de PORTA es 0, no pulsados
goto ENCIENDE_LOSDOS ; no se soltaron, vuelve a encender los dos
clrf PORTB    ; apagamos intermitentes
clrf CONTADOR
clrf CONTADOR_1
return

ENCIENDE_LOSDOS

bcf INTCON,2
movlw  0x18
movwf PORTB  ; ponemos a 1 bits 3 y 4 del puerto B
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_I
goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_LOSDOS

clrf    PORTB  ; lo hago asi porque supongo que no tienes mas cosas coectadas en PORTB
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc  PUL_I
goto  DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador
goto    ENCIENDE_LOSDOS


ANTIRREBOTES               ;

DEMORA  movlw     .110      ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .181      ; 1 set numero de repeticion  (A)
        movwf     PDel1     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        clrwdt              ; 1 ciclo delay
        decfsz    PDel1,1   ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel0,1   ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  goto PDelL3         ; 2 ciclos delay
PDelL3  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


ANTIRREBOTES_1 ; antirrebotes de 20ms solo cuando esta funcionando uno
; y se cambia para el otro, sin pasar por MAIN
movlw     .21       ; 1 set numero de repeticion  (B)
        movwf     PDel2     ; 1 |
PLoop3  movlw     .237      ; 1 set numero de repeticion  (A)
        movwf     PDel3     ; 1 |
PLoop4  clrwdt              ; 1 clear watchdog
        decfsz    PDel3,1   ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop4    ; 2 no, loop
        decfsz    PDel2,1   ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop3    ; 2 no, loop
PDelL4  goto PDelL5         ; 2 ciclos delay
PDelL5  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


END

Desconectado ohsielos

  • PIC10
  • *
  • Mensajes: 21
Re: Intermitentes moto.
« Respuesta #26 en: 20 de Diciembre de 2010, 10:39:25 »
Hola Tapi8.

Me pasé el finde con los programas de Juan47 y el tuyo.
.-El de Juan no conseguí hacerlo funcionar intentando adecuar los pulsadores y los leds a las salidas donde tenía montado mi circuito, ya que los tengo en una plaquita soldado, no en una protoboard que supongo que es mas fácil cambiar la configuración de entradas/salidas.
.- El tuyo eliminando las partes que llamaban a cambia_i y cambia_d, sí iba bastante bien aunque a veces se quedaba pillado y no quería parpadear a la primera pulsación.

Acabo de probar el que me acabas de dejar hoy, y con un cambio va perfecto al 100%  :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/
responde a la primera, los cambios sin titubeos y las luces de emergencia, tras el 'arreglo' también van estupendamente.

Te explico el fallo (quizás mas que fallo fue un lapsus): al probarlo todo iba bien salvo las luces de emergenca (los 4 intermitentes a la vez) que no arrancaban. Comparé con el que me dejaste el día 15 y ví las líneas que añadiste. Les puse el ';' delante para saltarlas e iba bien, salvo que cuando pulsaba un botón para que saliera del estado de emergencia, según el botón con que lo hiciese ahí se iba a parpadear.
Pues dándole vueltas, probé a cambiar las dos líneas en las subrutinas 'LOS_DOS' y 'DESACTIVAR_LOSDOS' que dicen: btfss   STATUS,Z por btfsc  STATUS,Z   y ya va de PM.

Por tanto esto se queda finiquitado. Por cierto cabrá en el 12F629???

Tapi8 estás hecho un gurú de los micropics. Has dado en la diana sin ver los fallos, me quito la gorra..

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Intermitentes moto.
« Respuesta #27 en: 21 de Diciembre de 2010, 13:39:56 »
Si fuera un guru hubiera funcionado a la primera :lol: :lol: La verdad es que a la primera nunca me funciono ninguno.

Le he estado dando vueltas a las luces de emegencia, porque en el MPLAB me van perfectas asi como las puse, y llego a la conclusion de que el primer antirrebotes el de 100ms es demasiado corto, por lo que ya te explique en otras ocasiones, a lo mejor es obsesion mia, porque soy torpe para esas cosas, pero apretar dos botones al mismo tiempo y que nunca haya una diferencia entre ambas pulsaciones de 100ms, yo estoy seguro que no lo haria, de 10 veces es posible que lo haga bien 3 o 4 pero el resto encenderia el de un lado o el del otro. He tratado de probar esto en el MPLAB y al hacer las dos pulsaciones con una diferencia de 100ms, se va a un lado y en cuanto enciende ese lado como el otro esta pulsado cambia y se hace de la picha un lio  :lol:.
Para solucionar esto te propongo o bien aumentar ese retardo a 300 o 400 o incluso 500ms, o si quieres hacemos que los 4 intermitentes enciandan pulsando un pulsador solo, el que mas te guste, durante un poco mas de tiempo, que porejemplo hasta 1.5s encienda ese intermitente y con una por encima de ese tiempo enciendan lo 4.

En cuanto a si el programa coge en el 16f629 no hay problema tiene 1KWORD (1024) de memoria de programa igual que el 16f84 y el programa aun con las ultimas modificaciones tiene 269 instrucciones, esto lo puedes mirar en el MPLAB vas a view, y en el desplegable te aparece Memory usage gauge la tercera del final pulsas y ya te dice lo que ocupa el programa.
Para que bajes si quieres el datasheet del 16f629, asi os vais conociendo :lol:

http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010113

Has comprobado si se te calienta algo en el circuito? sobre todo los transistores y el 7805, teniendolo tiempo encendido y puteandolo un poco, le pones de encendido en vez de 50ms, 4 min. por ejemplo. Eso lo haces variando ese 1 que hay en el encendido de las tres secuencias y si tienes a mano un tester mide que tension te cae entre emisor-colector cuando conduce, no deberia pasar de 2V, lo ideal es que este sobre 1.2V o 1.5V. y mira si el 7805 se calienta despues de estar tiempo trabajando, no deberia ya que el consumo del pic es bajo pero se jala 4v ahora y despues en la moto se va a comer 7V. Si hubiera problemas con el, los hay mejores, pero si con ese va bien, pues listo.

Bueno todavia no te felicito las fiestas porque hablaremos antes de navidad.  :lol:

Desconectado ohsielos

  • PIC10
  • *
  • Mensajes: 21
Re: Intermitentes moto.
« Respuesta #28 en: 21 de Diciembre de 2010, 16:40:53 »
Vale, un gurú no....un crack.  :)
Pues tal como está va perfecto al 100%. No pienso tocar nada del antirrebotes  :D
Desde luego, en modo emergencia, lo he tenido un par de minutos en marcha, alimentando desde 9v., y todo está completamente frío. Lo veo lógico, porque el tiempo que está encendido es 50ms cada casi 2 segundos, el transistor soporta 4A cuando lo previsto es un consumo de 1.4A (700mA x 2) en modo pulsante (50ms cada casi 2 segundos). Por ese lado estoy bastante tranquilo.
Puedo probar a que se quede encendido mas tiempo para ver como se comporta el transistor, porque el regulador solo alimenta al PIC, y con el 7805 de 1A va mas que sobrado. El regulador soporta voltajes de entrada hasta 35v.
Veré con el tester que caida hay en el transistor (solo tengo un lado puesto con opto, transistor, driver y led de alta potencia, en el izquierdo tengo una resistencia y un led de toda la vida).
 Seguimos en contacto....

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Intermitentes moto.
« Respuesta #29 en: 22 de Diciembre de 2010, 08:49:11 »
Citar
Si pulso ambos botones durante 1 segundo (o al mismo tiempo) parpadean los 4 indicadores sin fin (estado emergencia o avería) hasta que pulso los dos de nuevo.

Esto lo ponias tu en el primer post, los de Harley tambien ponen una temporizacion grande para distinguir entre pulsaciones.
Si a ti te gusta asi, listo la moto es tuya  :lol: :lol:
Si dentro de unos meses, andando ves que te falla esto ya sabes que el problema se soluciona asi, dandole un tiempo mas grande a antirrebotes, o si haces un circuito para un amigo que no sea tan rapido y preciso como tu  :lol: :lol:

Bueno felices fiestas por si ya no hablamos en una temporada.


 

anything