desktop

Curso de programación de PIC en PICBasic Pro

ayuda solucion para que no se reinicie el pic 16f876a sin carga funciona bien pero cuando conecto un motor o un foco se reinicia cuando quiere , puede funcionar bien durante 5 segundos y despues puede reiniciarse en cualquier momento, lo que lo separa es un triac con moc 3011 y y esta alimentado de un transformador le sigue un capacitor y un regulador tiene varios capacitores uno lo tiene bien serca de el pic de 100 nF, tambien ya desactive el watchdogtimer y lo mismo tambien medi con el tester me da como 40VAC en el pic se prende la luz con el buscapolo aunque no hay nada que este unido a fase pero sigue lo mismo se reinicia me vuelvo chango, alguna sugerencia , un filtro de linea? tal vez sera la solucion o algo en programacion?:unsure::cry:
 
ayuda solucion para que no se reinicie el pic 16f876a sin carga funciona bien pero cuando conecto un motor o un foco se reinicia cuando quiere , puede funcionar bien durante 5 segundos y despues puede reiniciarse en cualquier momento, lo que lo separa es un triac con moc 3011 y y esta alimentado de un transformador le sigue un capacitor y un regulador tiene varios capacitores uno lo tiene bien serca de el pic de 100 nF, tambien ya desactive el watchdogtimer y lo mismo tambien medi con el tester me da como 40VAC en el pic se prende la luz con el buscapolo aunque no hay nada que este unido a fase pero sigue lo mismo se reinicia me vuelvo chango, alguna sugerencia , un filtro de linea? tal vez sera la solucion o algo en programacion?:unsure::cry:

Con el motor me parece que es normal que se reinicie (causas del fenomeno EMI), y me parece que deberias poner un filtro para red, y quizas una jaula de faraday, con el foco me parece bastante raro que te pase, algo debes estar haciendo mal pero sin esquema y codigo seria dificil darte una opinion.
 
Buenas, les escribo a ver si alguien me ayuda con un problemita que tengo. La verdad no logro encontrar como solucionarlo, he hecho una cantidad de cosas y nada. Espero me puedan ayudar.

Estoy intentando a traves del PIC generar tonos dtmf, con la funcion DTMFOUT, y paralelamente mostrar en un 7 segmentos el numero presionado en un teclado 4x3.

El problema consiste en que cuando coloco las rutinas del DTMFOUT me salen errores en la simulacion con PROTEUS y comienzan a sonar y mostrarse todos los numeros de primerazo y solo despues es que me permite presionar el teclado y de ahi en adelante si funciona bien.

Les adjunto la simulacion, el codigo que estoy utilizando es el siguiente:

Código:
DEFINE OSC 4 ; Defíne oscilador externo de 4 MHZ.
cmcon = 7    ; Cambiar a modo digital todo el puerto A
TRISA = 0    ; Todo el puerto A es configurado como salidas
TRISB = %11110000 ; Configuracion del Puerto B [Teclado]

'****************************************************************
'*                    DEFINICION DE VARIABLES
'****************************************************************

' Nombres para los pines de las filas del teclado
A VAR PORTB.0 
B VAR PORTB.1
C VAR PORTB.2
D VAR PORTB.3
' Nombres para los pines de las columnas del teclado
UNO VAR PORTB.4
DOS VAR PORTB.5
TRES VAR PORTB.6
SPEAKER VAR PORTB.7
                 
PORTB = %11111111
PORTA = 15

'****************************************************************
'                       BARRIDO DEL TECLADO
'****************************************************************

BARRIDO:
LOW A ' Poner en bajo la 1ra fila
    IF UNO = 0 THEN PORTA = 1 : DTMFOUT SPEAKER,[1] 
    IF DOS = 0 THEN PORTA = 2 : DTMFOUT SPEAKER,[2]
    IF TRES = 0 THEN PORTA = 3 : DTMFOUT SPEAKER,[3]
HIGH A ' Poner en alto la 1ra fila

LOW B ' Poner en bajo la 2da fila
    IF UNO = 0 THEN PORTA = 4 : DTMFOUT SPEAKER,[4]
    IF DOS = 0 THEN PORTA = 5 : DTMFOUT SPEAKER,[5]
    IF TRES = 0 THEN PORTA = 6 : DTMFOUT SPEAKER,[6]
HIGH B ' Poner en alto la 2da fila

LOW C ' Poner en bajo la 3ra fila
    IF UNO = 0 THEN PORTA = 7 : DTMFOUT SPEAKER,[7]
    IF DOS = 0 THEN PORTA = 8 : DTMFOUT SPEAKER,[8]
    IF TRES = 0 THEN PORTA = 9 : DTMFOUT SPEAKER,[9]
HIGH C ' Poner en alto la 3ra fila

LOW D ' Poner en bajo la 4ta fila
    IF UNO = 0 THEN PORTA = 15 : DTMFOUT SPEAKER,[10]
    IF DOS = 0 THEN PORTA = 0 : DTMFOUT SPEAKER,[0]
    IF TRES = 0 THEN PORTA = 15 : DTMFOUT SPEAKER,[11]
HIGH D ; Poner en alto la 4ta fila

PAUSE 10 ; Pausa de 10 milisegundos
GOTO BARRIDO ' Continuar con el barrido de teclas
END

Gracias de antemano a todo aquel que me pueda ayudar.
Saludos desde Cartagena-Colombia :D
 

Adjuntos

  • DTMF_Generador JeyZG.zip
    19.3 KB · Visitas: 89
  • DTMF_Generador.jpg
    DTMF_Generador.jpg
    141.8 KB · Visitas: 64
Buenas, les escribo a ver si alguien me ayuda con un problemita que tengo. La verdad no logro encontrar como solucionarlo, he hecho una cantidad de cosas y nada. Espero me puedan ayudar.

Estoy intentando a traves del PIC generar tonos dtmf, con la funcion DTMFOUT, y paralelamente mostrar en un 7 segmentos el numero presionado en un teclado 4x3.

El problema consiste en que cuando coloco las rutinas del DTMFOUT me salen errores en la simulacion con PROTEUS y comienzan a sonar y mostrarse todos los numeros de primerazo y solo despues es que me permite presionar el teclado y de ahi en adelante si funciona bien.

Les adjunto la simulacion, el codigo que estoy utilizando es el siguiente:

Código:
DEFINE OSC 4 ; Defíne oscilador externo de 4 MHZ.
cmcon = 7    ; Cambiar a modo digital todo el puerto A
TRISA = 0    ; Todo el puerto A es configurado como salidas
TRISB = %11110000 ; Configuracion del Puerto B [Teclado]

'****************************************************************
'*                    DEFINICION DE VARIABLES
'****************************************************************

' Nombres para los pines de las filas del teclado
A VAR PORTB.0 
B VAR PORTB.1
C VAR PORTB.2
D VAR PORTB.3
' Nombres para los pines de las columnas del teclado
UNO VAR PORTB.4
DOS VAR PORTB.5
TRES VAR PORTB.6
SPEAKER VAR PORTB.7
                 
PORTB = %11111111
PORTA = 15

'****************************************************************
'                       BARRIDO DEL TECLADO
'****************************************************************

BARRIDO:
LOW A ' Poner en bajo la 1ra fila
    IF UNO = 0 THEN PORTA = 1 : DTMFOUT SPEAKER,[1] 
    IF DOS = 0 THEN PORTA = 2 : DTMFOUT SPEAKER,[2]
    IF TRES = 0 THEN PORTA = 3 : DTMFOUT SPEAKER,[3]
HIGH A ' Poner en alto la 1ra fila

LOW B ' Poner en bajo la 2da fila
    IF UNO = 0 THEN PORTA = 4 : DTMFOUT SPEAKER,[4]
    IF DOS = 0 THEN PORTA = 5 : DTMFOUT SPEAKER,[5]
    IF TRES = 0 THEN PORTA = 6 : DTMFOUT SPEAKER,[6]
HIGH B ' Poner en alto la 2da fila

LOW C ' Poner en bajo la 3ra fila
    IF UNO = 0 THEN PORTA = 7 : DTMFOUT SPEAKER,[7]
    IF DOS = 0 THEN PORTA = 8 : DTMFOUT SPEAKER,[8]
    IF TRES = 0 THEN PORTA = 9 : DTMFOUT SPEAKER,[9]
HIGH C ' Poner en alto la 3ra fila

LOW D ' Poner en bajo la 4ta fila
    IF UNO = 0 THEN PORTA = 15 : DTMFOUT SPEAKER,[10]
    IF DOS = 0 THEN PORTA = 0 : DTMFOUT SPEAKER,[0]
    IF TRES = 0 THEN PORTA = 15 : DTMFOUT SPEAKER,[11]
HIGH D ; Poner en alto la 4ta fila

PAUSE 10 ; Pausa de 10 milisegundos
GOTO BARRIDO ' Continuar con el barrido de teclas
END
Gracias de antemano a todo aquel que me pueda ayudar.
Saludos desde Cartagena-Colombia :D

Hola...activa la opción del Pull-Up del puerto B como lo resalto en en color azul:
Código:
DEFINE OSC 4 ; Defíne oscilador externo de 4 MHZ.
@cmcon = 7    ; Cambiar a modo digital todo el puerto A
[COLOR=Blue]OPTION_REG = 0 ; Pull-UP puerto B activado[/COLOR]
TRISA = 0    ; Todo el puerto A es configurado como salidas
TRISB = %11110000 ; Configuracion del Puerto B [Teclado]

La otra opción es colocar en las cuatro entradas del puerto B las resistencias de pull-up a +B individualmente.
Saludos.

Ric.
 
Saludos, solicito humildemente una orientacion si es que existe un operador en pic basic que me permita realizar un programa para realizar un decodificador de BCD (binario) a decimal, poseo 4 datos en binario y quisiera representar la sgte tabla de datos, en el encendido de 8 leds, sin necesidad de usar decodificadores como el 4028, sino realizarlo con pic 16F628 para practicar la conversion de binario a decimal, ya que no encuentro orientacion sobre este tema por ningun lado en este lenguaje que es en el que intento aprender con practicas e imagino que este es uno de los primeras practicas que todo aprendiz deberia realizar y dominar, mil gracias por su tiempo y si s posible algun ejemplo de como afrontar esta practica y organizar dichos datos dentro del programa. (utilizando el PTO A como entrada y el PTO B como salida)

D C B A
0 0 0 1 ENCIENDE LED 1
0 0 1 0 2
0 0 1 1 3
0 1 0 0 4
0 1 0 1 5
0 1 1 0 6
0 1 1 1 7
1 0 0 0 8


Como veran, esta disposicion corresponde a la tabla de verdad del decodificador 4028 y simplemente tome al azar este deco, pudiendo usar la tabla de cualquier otro, simplemente lo que deseo es aprender como organizar estos datos dentro de un programa y que efectue el mismo trabajo que realiza este deco, ya que imagino que dominando esto, podria alcanzar las 15 posibilidades que me brinda codificar con 4 bits de entrada y como no conozco de ningun decodificador que tenga estas 16 posibilidades Los que conozco son decimales), pues creo que seria muy util para muchos colegas en sus proyectos . Agracezco mucho cualquier informacion y ayuda que me puedan brindar.
 
Saludos, solicito humildemente una orientacion si es que existe un operador en pic basic que me permita realizar un programa para realizar un decodificador de BCD (binario) a decimal, poseo 4 datos en binario y quisiera representar la sgte tabla de datos, en el encendido de 8 leds, sin necesidad de usar decodificadores como el 4028, sino realizarlo con pic 16F628 para practicar la conversion de binario a decimal, ya que no encuentro orientacion sobre este tema por ningun lado en este lenguaje que es en el que intento aprender con practicas e imagino que este es uno de los primeras practicas que todo aprendiz deberia realizar y dominar, mil gracias por su tiempo y si s posible algun ejemplo de como afrontar esta practica y organizar dichos datos dentro del programa. (utilizando el PTO A como entrada y el PTO B como salida)

D C B A
0 0 0 1 ENCIENDE LED 1
0 0 1 0 2
0 0 1 1 3
0 1 0 0 4
0 1 0 1 5
0 1 1 0 6
0 1 1 1 7
1 0 0 0 8


Como veran, esta disposicion corresponde a la tabla de verdad del decodificador 4028 y simplemente tome al azar este deco, pudiendo usar la tabla de cualquier otro, simplemente lo que deseo es aprender como organizar estos datos dentro de un programa y que efectue el mismo trabajo que realiza este deco, ya que imagino que dominando esto, podria alcanzar las 15 posibilidades que me brinda codificar con 4 bits de entrada y como no conozco de ningun decodificador que tenga estas 16 posibilidades Los que conozco son decimales), pues creo que seria muy util para muchos colegas en sus proyectos . Agracezco mucho cualquier informacion y ayuda que me puedan brindar.

Hola inspector gadget, creo que esto te puede ayudar...

Código:
CMCON = 7                       ; TODOS LOS PINES COMO DIGITALES
TRISA = %00001111               ; RA0 a RA3 COMO ENTRADAS
TRISB = %00000000               ; PUERTO B COMO SALIDA

SYMBOL A = PORTA.0
SYMBOL B = PORTA.1
SYMBOL C = PORTA.2
SYMBOL D = PORTA.3

PORTB = %11111111               ; APAGA TODOS LOS LEDS ANTES DE EMPEZAR

Main:                           ; PROGRAMA PRINCIPAL

'COMBINACIONES SEGUN LA TABLA DE VERDAD QUE PUSISTE
IF D = 0 AND C = 0 AND B = 0 AND A = 0 THEN PORTB = %11111111 'APAGA TODOS
IF D = 0 AND C = 0 AND B = 0 AND A = 1 THEN PORTB = %11111110 'LED1
IF D = 0 AND C = 0 AND B = 1 AND A = 0 THEN PORTB = %11111101 'LED2
IF D = 0 AND C = 0 AND B = 1 AND A = 1 THEN PORTB = %11111011 'LED3
IF D = 0 AND C = 1 AND B = 0 AND A = 0 THEN PORTB = %11110111 'LED4
IF D = 0 AND C = 1 AND B = 0 AND A = 1 THEN PORTB = %11101111 'LED5
IF D = 0 AND C = 1 AND B = 1 AND A = 0 THEN PORTB = %11011111 'LED6
IF D = 0 AND C = 1 AND B = 1 AND A = 1 THEN PORTB = %10111111 'LED7
IF D = 1 AND C = 0 AND B = 0 AND A = 0 THEN PORTB = %01111111 'LED8
Goto MAIN                       ; BUCLE INFINITO
END

Existiran varias formas de hacerlo, esta está hecha a mi manera :LOL:
Te adjunto un .ZIP con la simulación y el código anterior. Espero que te sirva

Saludos!
 

Adjuntos

  • BCD2DEC.zip
    237.7 KB · Visitas: 94
  • Simulacion.jpg
    Simulacion.jpg
    137.4 KB · Visitas: 57
buenos días, saludos a todos los foreros. Gracias a MrCarlos por el dato, lastimosamente no tengo idea de assembler que es el lenguaje de ese proyecto.
Muchísimas gracias Jey1124 por tomarte el tiempo de asesorarme, crear la simulación y hacerme caer en cuenta de varias cosas que tenia mal en el programa que quería realizar y aunque no lo postee, aquí esta como empece y si bien es cierto que hay varias posibilidades de encarar el programa, pues con la forma que lo hiciste, aclare varios conceptos y funciona muy bien. Aquí esta como lo intente realizar:

Código:
cmcon=7
TrisA = 255 'todos como entrada
TrisB = 0 'todos como salida

;configuracion de pines 
led1 var portb.0  
led2 var portb.1 
led3 var portb.2 
led4 var portb.3 
led5 var portb.4 
led6 var portb.5 
led7 var portb.6 
led8 var portb.7 

p1 var porta.0 
p2 var porta.1 
p3 var porta.2 
p4 var porta.3 

 PortB=0
inicio:
 if (P1=1) then led1=1
 if (P2=1) and (p3=1) and (p4=1) then led2=1
 if (P2=1) and (p3=1)  then led3=1
 if (P2=1) and (p4=1)  then led4=1
 if (P2=1) then led5=1
 if (P3=1) and (p4=1)  then led6=1
 if (P3=1) then led7=1
 if (P4=1) then led8=1
 
Goto inicio

Bien, aunque el programa anterior no esta configurado correctamente, el que creó Jey, me deja bastantes cosas en claro.
Ahora lo que pretendo es mantener el estado de la salida, enclavado, aunque desaparezcan los datos de entrada, y luego cuando aparezcan nuevamente LOS MISMOS datos de entrada que lo hicieron encender, el led se vuelve a apagar.
Me explico: tomo como ejemplo los datos de entrada del encendido del primer led

IF D = 0 AND C = 0 AND B = 0 AND A = 0 THEN PORTB = %11111111 'APAGA TODOS
IF D = 0 AND C = 0 AND B = 0 AND A = 1 THEN PORTB = %11111110 ; enciende led 1
TOGGLE PORTB = %11111110
el led debe permanecer encendido, aunque los datos de entrada del PTO A desaparezcan y cuando vuelvan a aparecer los mismos datos, el led debe apagarse,
opte por usar la instrucción toggle para invertir l estado de la salida, pero parece no ser lo adecuado, en verdad no se como seguir adelante y pido su opinión como debería quedar, para así emplearla en todos los led, algo así como funciona un control ON-OFF digital pero con cuatro datos de entrada, Agradezco a quienes me puedan colaborar en como realizarlo, ya que para algunos de nosotros que nos ha tocado aprender preguntando en los foros y descargando información, ustedes son nuestra única opción de educación en este sentido, muchas gracias nuevamente.
 
Última edición por un moderador:
buenos dias, saludos a todos los foreros. Gracias a MrCarlos por el dato, lastimosamente no tengo idea d assembler que es el lenguaje de ese proyecto.
Muchisimas gracias Jey1124 por tomarte el tiempo de asesorarme, crear la simulacion y hacerme caer en cuenta de varias cosas que tenia mal en eel programa que queria realizar y aunque no lo postee, aqui esta como empece y si bien es cierto que hay varias posibilidades de encarar el programa, pues con la forma que lo hiciste, aclare varios conceptos y funciona muy bien. Aqui esta como lo intente ralizar:

cmcon=7
TrisA = 255 'todos como entrada
TrisB = 0 'todos como salida

;configuracion de pines
led1 var portb.0
led2 var portb.1
led3 var portb.2
led4 var portb.3
led5 var portb.4
led6 var portb.5
led7 var portb.6
led8 var portb.7

p1 var porta.0
p2 var porta.1
p3 var porta.2
p4 var porta.3

PortB=0
inicio:
if (P1=1) then led1=1
if (P2=1) and (p3=1) and (p4=1) then led2=1
if (P2=1) and (p3=1) then led3=1
if (P2=1) and (p4=1) then led4=1
if (P2=1) then led5=1
if (P3=1) and (p4=1) then led6=1
if (P3=1) then led7=1
if (P4=1) then led8=1

Goto inicio

Bien, aunque el programa anterior no esta configurado correctamente, el qu creò Jey, me deja bastantes cosas en claro.
Ahora lo que pretendo es mantener el estado de la salida, enclavado, aunque desaparezcan los datos de entrada, y luego cuando aparezcan nuevamente LOS MISMOS datos de entrada que lo hicieron encender, el led se vuelve a apagar.
Me explico: tomo como ejemplo los datos de entrada del encendido del primer led

IF D = 0 AND C = 0 AND B = 0 AND A = 0 THEN PORTB = %11111111 'APAGA TODOS
IF D = 0 AND C = 0 AND B = 0 AND A = 1 THEN PORTB = %11111110 ; enciende led 1
TOGGLE PORTB = %11111110
el led debe permanecer encendido, aunque los datos de entrada del PTO A desaparezcan y cuando vuelvan a aparecer los mismos datos, el led debe apagarse,
opte por usar la instruccion toggle para invertir l estado de la salida, pero parece no ser lo adecuado, en verdad no se como seguir adelante y pido su opinion como deberia quedar, para asi emplearla en todos los led, algo asi como funciona un control ON-OFF digital pero con cuatro datos de entrada, Agradezco a quienes m puedan colaborar en como realizarlo, ya que para algunos de nosotros que nos ha tocado aprender preguntando n los foros y descargando informacion, uds son nuestra unica opcion de educacion en este sentido, muchas gracias nuevamente.

Buenas noches, intentando colaborarte un poco, diseñe lo siguiente (Creo que cumple con lo que quieres, debes hacer las pruebas, aunque ya yo probé y funciona 100% pero no se si es lo que buscas)

Código:
CMCON = 7                       ; TODOS LOS PINES COMO DIGITALES
TRISA = %00001111               ; RA0 a RA3 COMO ENTRADAS
TRISB = %00000000               ; PUERTO B COMO SALIDA

SYMBOL A = PORTA.0
SYMBOL B = PORTA.1
SYMBOL C = PORTA.2
SYMBOL D = PORTA.3
TMP1 VAR BIT
TMP2 VAR BIT
TMP3 VAR BIT
TMP4 VAR BIT
TMP5 VAR BIT
TMP6 VAR BIT
TMP7 VAR BIT
TMP8 VAR BIT

PORTB = %11111111               ; APAGA TODOS LOS LEDS ANTES DE EMPEZAR

Main:                           ; PROGRAMA PRINCIPAL

'COMBINACIONES SEGUN LA TABLA DE VERDAD QUE PUSISTE
IF D = 0 AND C = 0 AND B = 0 AND A = 0 THEN 
    TMP1 = 0 : TMP2 = 0 : TMP3 = 0 : TMP4 = 0 : TMP5 = 0 : TMP6 = 0 : TMP7 = 0 : TMP8 = 0
ENDIF
IF D = 0 AND C = 0 AND B = 0 AND A = 1 THEN 
    IF TMP1 = 0 THEN
        PORTB.0 = not PORTB.0 'LED1
        TMP1 = 1 : TMP2 = 0 : TMP3 = 0 : TMP4 = 0 : TMP5 = 0 : TMP6 = 0 : TMP7 = 0 : TMP8 = 0
    ELSE
        PORTB.0 = PORTB.0
    ENDIF
ENDIF
IF D = 0 AND C = 0 AND B = 1 AND A = 0 THEN 
    IF TMP2 = 0 THEN
        PORTB.1 = not PORTB.1 'LED2
        TMP1 = 0 : TMP2 = 1 : TMP3 = 0 : TMP4 = 0 : TMP5 = 0 : TMP6 = 0 : TMP7 = 0 : TMP8 = 0
    ELSE
        PORTB.1 = PORTB.1
    ENDIF
ENDIF
IF D = 0 AND C = 0 AND B = 1 AND A = 1 THEN 
    IF TMP3 = 0 THEN
        PORTB.2 = not PORTB.2 'LED3
        TMP1 = 0 : TMP2 = 0 : TMP3 = 1 : TMP4 = 0 : TMP5 = 0 : TMP6 = 0 : TMP7 = 0 : TMP8 = 0
    ELSE
        PORTB.2 = PORTB.2
    ENDIF
ENDIF
IF D = 0 AND C = 1 AND B = 0 AND A = 0 THEN 
    IF TMP4 = 0 THEN
        PORTB.3 = not PORTB.3 'LED4
        TMP1 = 0 : TMP2 = 0 : TMP3 = 0 : TMP4 = 1 : TMP5 = 0 : TMP6 = 0 : TMP7 = 0 : TMP8 = 0
    ELSE
        PORTB.3 = PORTB.3
    ENDIF
ENDIF
IF D = 0 AND C = 1 AND B = 0 AND A = 1 THEN 
    IF TMP5 = 0 THEN
        PORTB.4 = not PORTB.4 'LED5
        TMP1 = 0 : TMP2 = 0 : TMP3 = 0 : TMP4 = 0 : TMP5 = 1 : TMP6 = 0 : TMP7 = 0 : TMP8 = 0
    ELSE
        PORTB.4 = PORTB.4
    ENDIF    
ENDIF
IF D = 0 AND C = 1 AND B = 1 AND A = 0 THEN 
    IF TMP6 = 0 THEN
        PORTB.5 = not PORTB.5 'LED6
        TMP1 = 0 : TMP2 = 0 : TMP3 = 0 : TMP4 = 0 : TMP5 = 0 : TMP6 = 1 : TMP7 = 0 : TMP8 = 0
    ELSE
        PORTB.5 = PORTB.5
    ENDIF    
ENDIF
IF D = 0 AND C = 1 AND B = 1 AND A = 1 THEN 
    IF TMP7 = 0 THEN
        PORTB.6 = not PORTB.6 'LED7
        TMP1 = 0 : TMP2 = 0 : TMP3 = 0 : TMP4 = 0 : TMP5 = 0 : TMP6 = 0 : TMP7 = 1 : TMP8 = 0
    ELSE
        PORTB.6 = PORTB.6
    ENDIF    
ENDIF
IF D = 1 AND C = 0 AND B = 0 AND A = 0 THEN 
    IF TMP8 = 0 THEN
        PORTB.7 = not PORTB.7 'LED8
        TMP1 = 0 : TMP2 = 0 : TMP3 = 0 : TMP4 = 0 : TMP5 = 0 : TMP6 = 0 : TMP7 = 0 : TMP8 = 1
    ELSE
        PORTB.7 = PORTB.7
    ENDIF    
ENDIF
Goto MAIN                       ; BUCLE INFINITO
End

No soy el mas experto en programación, y no se que tan viable sea el código anterior, pero si soy recursivo y todavia esa recursividad me funciona jaja. Espero que te sirva a ti y a cualquier otra persona que llegue a necesitarlo.

Puedes utilizar la misma simulacion que te pase antes para probarlo, los cambios solo son de codigo. Analizalo :D

PD: Te adjunto el un .ZIP con los archivos necesarios (.PBP, .DSN, .HEX)
 

Adjuntos

  • BCD2DEC_2.zip
    140.5 KB · Visitas: 85
Excelente aporte jey1124 muchisimas gracias por sacar tiempo para colaborar con los que le estamos siguiendo el hilo a la programacion. El programa funciona bien y me sirve mucho para mis practicas, esta bastante claro y salvo unos bits que yo habia puesto mal, solo fue cuestion de analizarlo y acomodarlo a mi necesidad, ahora que ya lo probe voy a agregarle una pantalla lcd para visualisar la activacion de la salida correspondiente en lugar de los led, simplemente es para continuar las practicas, ya que se han visto elementos de entrada ahora voy con las salidas con lcd para que quede completo, como no se mucho de lcd voy a hacer algunas pruebas, ojala y me puedas seguir colaborando si se presentan dudas en el camino, muchas gracias Jey y toda la comunidad de los foros.
 
Hola a todos
aquí les dejo estos vídeos archivos del driver para servomotores de CD con encoder en cuadratura (OJO NO SON SERVOMOTORES DE AEROMODELISMO SON SERVOMOTORES INDUSTRIALES)

video corto de robot moviéndose en el plano

gracias a este foro y el aporte de muchos de ustedes como autotronico, mecatrodatos, lubeck, darkbyte, reyvilla, meta, chico3001, etc

codigo en proton
Código:
Declare Warnings = OFF
Device 18F4431
Xtal = 20
'include "modedefs.bas"

'All_Digital = True 
    Float_Display_Type = Fast	' Use the fast floating point display library
	Optimiser_Level = 2			' Optimise the code
	
Config_Start
   OSC = HS ; HS oscillator
   PWRTEN = OFF ; PWRT disabled
   BOREN = OFF ; Brown-out Reset disabled in hardware and software
   WDTEN = OFF ; WDT disabled (control is placed on the SWDTEN bit)
   MCLRE = OFF ; RE3 input pin enabled; MCLR disabled
   LVP = OFF ; Disabled
   Debug = OFF ; Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
Config_End
 
Declare Hserial_Baud  = 9600                 ' Set baud rate for USART 1
Declare Hserial_RCSTA = %10010000           ' Enable serial port and continuous receive
Declare Hserial_TXSTA = %00100100           ' Enable transmit and asynchronous mode
Declare Hserial_Clear = On
'
Symbol GIE = INTCON.7
Symbol CambioCW = PIR3.3
Symbol Desbordamiento = PIR3.2
Symbol Sentido = QEICON.5

INTCON = %11000000 ' activamos las interrupciones y las de periféricos

On_Interrupt GoTo serie
PIE1.5 = 1 ' activamos la interrupción de recepción de la USART

Sentido=0
Desbordamiento=0

TRISD = %00000000

Declare LCD_Type 0          ' Type of LCD Used is Alpha
Declare LCD_DTPin PORTD.4   ' The control bits B4,B5,B6,B7
Declare LCD_RSPin PORTE.0  ' RS pin on B2
Declare LCD_ENPin PORTE.1   ' E pin on B3
Declare LCD_Interface 4     ' Interface method is 4 bit

Declare CCP1_Pin PORTC.2
Declare CCP2_Pin PORTC.1
'------------Variables-------------
 Dim DATO[9]   As   Byte
 Dim NUM[9]    As   Byte
 Dim I As Byte
 Dim INDICE    As   Byte
 Dim DATOE     As    Byte
 'Dim DATOACUM1 As Word
 Dim DATOACUM As Dword
 Dim DATOS As Word
 Dim   mot_pwr  As    Dword  
 Dim   recu_pos As    Dword
 Dim   Upos     As    Word
 Dim   vel      As    Word      
 Dim   pot_val  As    Byte        
 Dim   Posicion As    Word  
 Dim   Posicion2 As   Word
 Dim   posH     As    Byte
 Dim   posL     As    Byte
 Dim   posHtem  As    Byte   
 Dim   FreMot  As     Word
 Dim   a       As     Float
 Dim   b       As     Float
 Dim   c       As     Float
 Dim   rt      As     Float
 Dim   eT      As     Float
 Dim   iT      As     Float
 Dim   dT2     As     Float
 Dim   yT      As     Dword
 Dim   uT      As     Float
 Dim   iT0     As     Float
 Dim   eT0     As     Float
 Dim   vmax    As     Byte
 Dim   vmin    As     Byte   
 Dim   Pantalla As    Byte   
 Dim   sentido2 As    Byte	 
 Dim   Activo   As    Byte
'--------------------
    ANSEL0 = %00000001          
    ANSEL1 = %00000000            
    TRISA = %00011111          
    LATA  = %00000000           
    TRISB = %00000000           
    TRISC = %10010000      
    TRISD = %00000000    
    QEICON = %10011000          
    PORTC.0 = 0 '1                 
    PORTC.1 = 0 
    PORTD.0 =1                 
Print Cls
Print At 1,1," CARGANDO"
Print At 2,1," PARAMETROS"

DelayMS 10
PORTD.0=0
    
    FreMot = 16000                  'frecuencia para el hpwm
    PORTC.0 = 0                 
    PORTC.3 = 0                           
    Upos=1                                                         
    Posicion= 0                 'variable posicion real       
    Posicion2=0
    POSCNTH = 156                 'para tener un 2000 en posicion
    POSCNTL = 64         
    vmin= 75                   'pwm minimo para el motor
    vmax= 180                   'pwm maximo para el motor
    iT0= 0                      'variable para calulo de termino derivarivo
    eT0= 0                      'variable para calculo del error
    a = 0.50                        'parametro proporcional
    b = 0.0009                       'parametro integral
    c = 0.050                        'parametro derivativo
INDICE=0
DATOE=0
DATOACUM=0
mot_pwr = 40000 
recu_pos=40000
                'se le asigna una posicion de inicio.
Pantalla = 1
sentido2= 0
Activo=0
'*********************************************************************
'********************PROGRAMA PRINCIPAL********************************
'*********************************************************************             
lop:                                                                                           
    GoSub CalPos                'ir a calcular la posicion actual
    
    GoSub calvel               'calcular PWM para el motor
   
    If mot_pwr = yT Then  'se borra el acumulado del error
        iT0=0
        eT0=0
        sentido2 =0
        HPWM 1, 0, FreMot     'no sale PWM por CCP1
        HPWM 2, 0, FreMot       'por CCP2 no sale nada
    EndIf  
   
    If mot_pwr > yT Then  'si set point es mayor que posicion actual                         
        HPWM 1, vel, FreMot     'sale PWM por CCP1
        HPWM 2, 0, FreMot       'por CCP2 no sale nada
    ElseIf mot_pwr < yT Then 'en caso contrario posicion actual > set point
        HPWM 2, vel, FreMot     'no sale nada por CCP1  
        HPWM 1, 0, FreMot       'sale pwm por CCP2
    EndIf                             
   
   ' GoSub lcd                   'muestra informacion en LCD

    GoTo lop                      
 
 End  
' ***********************************************************************************
'*****************FIN PROGRAMA PRINCIPAL*********************************************
'************************************************************************************    
lcd:                            'sub que muestra en lcd
If Pantalla = 1 Then
    Print At 1,1, "p=",Dec5 mot_pwr," v=", Dec3 vel'Dec3 vel  
    Print At 2,1, "R=",Dec5 Posicion ," e=", Dec1 eT
    'HSerOut["pos=", dec yt, "*",13]
    'delayms 10
ElseIf Pantalla = 2 Then
    Print At 1,1, "P",Dec4 a," I", Dec4 b         'Dec3 vel  
    Print At 2,1, "D",Dec4 c ," e=", Dec1 eT
ElseIf Pantalla = 3 Then
    Print At 1,1, "p=",Dec5 mot_pwr," P", Dec3 a'Dec3 vel  
    Print At 2,1, "R=",Dec5 Posicion ," I", Dec4 b
EndIf                                                                                             
Return   
'********************************************************************************** 
CalPos:                        'sub para calcular posicion
    posH = POSCNTH
    posL = POSCNTL
    posHtem = POSCNTH
    If posH - posHtem = 0 Then GoTo Listo
    posH = POSCNTH
    posL = POSCNTL    
Listo:    
    Posicion = 256*posH + posL 'se convierte en 16 bit la pos
    If Desbordamiento = 1  Then
        Desbordamiento= 0
        
        If sentido2 = 1 Then
            Posicion2 =Posicion2 + 1
            'sentido2 =0
        ElseIf sentido2 =2 Then       
            Posicion2 =Posicion2 - 1
            'sentido2 =0
        EndIf
    EndIf
    yT= 65536 * Posicion2 + Posicion
    Return  
'*************************************************************************************    
'****************************************************************************************        
calvel:                  'CALCULO DEL PWM CON PID
    eT = Abs(mot_pwr - yT)  'calculo del error
    eT = eT * (360/1200)   'ESCALAMOS: 360 grados es a 2000 pulsos del encoder
    iT = b*eT + iT0      'calculo de valor integral (magnitud del error)
    dT2 = c * (eT - eT0)  'calculo del valor derivativo (tiempo de respuesta)
    uT = iT + a * eT 
    uT = uT + dT2 'valor del PID
    
    If uT> vmax Then      'si la salida del PID es mayor que el valor de PWM
        uT = vmax          'que puedo mandar asignale el valor 255
    Else
        If uT< vmin Then uT=vmin  'PWM minimo que quiero enviar
    EndIf
    vel=uT                'velocidad del motor en PWM
    iT0=iT 
    eT0=eT   
    Return      
    
    
'*********************interrupcion PUERTO SERIE ********************************    
serie:
Context Save
HSerIn [DATOE] ' recibo el caracter de la pc por el rs232
RCSTA.4=0
RCSTA.4=1


 
If DATOE=="y" Then
   'Activo = 1
   INDICE=0
    'HSerOut[activo]
    DelayMS 1
ElseIf DATOE=="x" Or DATOE=="z"  Then  
    'Activo = 0
    INDICE=0     
    recu_pos = mot_pwr
EndIf    

 DATO[INDICE]=DATOE
 INDICE=INDICE+1

If DATOE== "*"  Then  ' cuando del PC llaga un "*" interpreto el numero que recibi

  If DATO[0]=="y" Then
     INDICE=0
     For I=2 To 7
        Select Case DATO[I] 'dato que recibi
            Case 48                 ' es un cero?
                NUM[I]=0           
            Case 49                 ' es un uno?
                NUM[I]=1
            Case 50                 ' es un dos?
                NUM[I]=2
            Case 51                 'creo que ya entendieron....
                NUM[I]=3
            Case 52
                NUM[I]=4
            Case 53
                NUM[I]=5
            Case 54
                NUM[I]=6
            Case 55
                NUM[I]=7
            Case 56
                NUM[I]=8
            Case 57                   ' es un nueve?
                NUM[I]=9
            Case Else    'CUALQUIER OTRO CARACTER LO TOMA COMO CERO "O"
                NUM[I]=0
        End Select 
     Next I
     'aqui determino que numero me enviaron por el PC
     'DATOACUM1=NUM[7] + NUM[6]*10 + NUM[5]*100 + NUM[4]*1000 + NUM[3]*10000 
     DATOACUM = NUM[7] + NUM[6]*10 
     DATOACUM=DATOACUM + NUM[5]*100 
     DATOACUM =DATOACUM + NUM[4]*1000
     DATOACUM=DATOACUM  + NUM[3]*10000 
     DATOACUM=DATOACUM + NUM[2]*100000
    Select Case DATO[1]
        Case "p"
            mot_pwr=DATOACUM
            If mot_pwr > yT Then
                sentido2 = 1
            Else
                sentido2 = 2
            EndIf
        Case "V"
            If DATOACUM > vmin Then
                If DATOACUM > 255 Then
                    vmax = 255
                Else
                    vmax = DATOACUM
                End If 
            EndIf    
         Case "v"
            If DATOACUM < vmax Then
                If DATOACUM < 20 Then
                    vmin = 20
                ElseIf DATOACUM > 200 Then
                    vmin =200
                Else
                    vmin = DATOACUM
                End If  
            EndIf      
         Case "P"
            a = DATOACUM / 10000
         Case "I"
            b = DATOACUM / 10000
         Case "D"  
            c = DATOACUM / 10000
         Case "q"
            If DATO[2]="1" Then
                Pantalla=1
            ElseIf DATO[2]="2" Then
                Pantalla=2
            ElseIf DATO[2]="3" Then
                Pantalla=3
            EndIf
         Case "x"
             HSerOut[Dec6 yT]
             DelayMS 10
    End Select    
    
    'HSerOut[DATOE]                    'envio lo que recibo....nomas...
     'Activo = 0
    EndIf       
    
    If DATO[0]=="x" Then
         RCSTA.4=0
        RCSTA.4=1
        INDICE=0
        mot_pwr=recu_pos
    EndIf
EndIf

If DATO[0]=="y" Then
  HSerOut[DATOE]             'envio lo que recibo....nomas...
'Else
'    RCSTA.4=0
'    RCSTA.4=1  
EndIf

INTCON = %11000000
Context Restore

el codigo en pic basic esta en un post anterior
 

Adjuntos

  • driver_servo.rar
    92.3 KB · Visitas: 111
robot sigue al simulador

http://youtu.be/S5LkXVagbE8

el lunes les pongo el codigo todo comentado
si les interesa....
¿que si nos interesa? :eek: mas vale que nos interesa... sabes el tiempo que hace que quiero saber como se hace eso de hacer cinematica inversa? :eek: ponelo, pero explicalo lo mas simple que se pueda, asi puedo entender :LOL: ... es que soy muy burro jajaja :LOL: tambien me gustaria saber que programa usaste para hacer la simulacion y como se hace para combinar la programacion del pic con la computadora... saludos y desde ya que estoy esperando ese proyecto, no te olvides de postear un ejemplito de la simu :D
 
¿que si nos interesa? :eek: mas vale que nos interesa... sabes el tiempo que hace que quiero saber como se hace eso de hacer cinematica inversa? :eek: ponelo, pero explicalo lo mas simple que se pueda, asi puedo entender :LOL: ... es que soy muy burro jajaja :LOL: tambien me gustaria saber que programa usaste para hacer la simulacion y como se hace para combinar la programacion del pic con la computadora... saludos y desde ya que estoy esperando ese proyecto, no te olvides de postear un ejemplito de la simu :D

Que tal Dario
en este video explico la simulacion del driver

el martes te explico lo de la cinematica inversa
 
muy bueno el video amigo arturo... veo que tenes experiencia con el sistema P.I.D, eso es algo que me cuesta entender todavia :oops: justo en estos dias anduve pensando en hacer una practica con un motor DC y un encoder hecho apartir de un muse de pc de esos de bolita para ver si de una ves por todas puedo entenderlo... hice el intento varias veces de hacer un servo apartir de un motor dc con reduccion y un potenciometro pero nunca me salio ya que no estaba implementando el sistema P.I.D por no entender como funciona... saludosss (y)
 
Última edición:
Excelente proyecto... quedamos a la espera de más información, felicitaciones!
Quisiera aprovechar este espacio para preguntar.... como siempre... si alguien puede orientarme... han llegado a mis manos 2 displeys nokia 1100 y me ha picado la curiosidad que cómo activarlos, lo curioso es que todo lo que he buscado está hecho en C o CCS, no entiendo bien el lenguaje, además son códigos extensos que no logro descifrar con claridad, en fin, me gustaría poder simular en proteus un mensaje básico y creo que el documento adjunto es un buen punto de partida, pueden ayudarme?
 

Adjuntos

  • CONTROL LCD NOKIA 1100(lenguaje C).pdf
    62.4 KB · Visitas: 79
muy bueno el video amigo arturo... veo que tenes experiencia con el sistema P.I.D, eso es algo que me cuesta entender todavia :oops: justo en estos dias anduve pensando en hacer una practica con un motor DC y un encoder hecho apartir de un muse de pc de esos de bolita para ver si de una ves por todas puedo entenderlo... hice el intento varias veces de hacer un servo apartir de un motor dc con reduccion y un potenciometro pero nunca me salio ya que no estaba implementando el sistema P.I.D por no entender como funciona... saludosss (y)

Dario
me equivoque de vídeo este esta mas completo

este es el código comentado
Código:
Declare Warnings = OFF
Device 18F4431
Xtal = 20
'All_Digital = True 
    Float_Display_Type = Fast	' Use the fast floating point display library
	Optimiser_Level = 3			' Optimise the code
	
Config_Start
   OSC = HS ; HS oscillator
   PWRTEN = OFF ; PWRT disabled
   BOREN = OFF ; Brown-out Reset disabled in hardware and software
   WDTEN = OFF ; WDT disabled (control is placed on the SWDTEN bit)
   MCLRE = OFF ; RE3 input pin enabled; MCLR disabled
   LVP = OFF ; Disabled
   Debug = OFF ; Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
Config_End
 
Declare Hserial_Baud  = 9600                 ' Set baud rate for USART 1
Declare Hserial_RCSTA = %10010000           ' Enable serial port and continuous receive
Declare Hserial_TXSTA = %00100100           ' Enable transmit and asynchronous mode
Declare Hserial_Clear = On
'
Symbol GIE = INTCON.7
Symbol CambioCW = PIR3.3
Symbol Desbordamiento = PIR3.2
Symbol Sentido = QEICON.5

INTCON = %11000000 ' activamos las interrupciones y las de periféricos

On_Interrupt GoTo serie
PIE1.5 = 1 ' activamos la interrupción de recepción de la USART

Sentido=0
Desbordamiento=0

TRISD = %00000000

Declare LCD_Type 0          ' Type of LCD Used is Alpha
Declare LCD_DTPin PORTD.4   ' The control bits B4,B5,B6,B7
Declare LCD_RSPin PORTE.0  ' RS pin on B2
Declare LCD_ENPin PORTE.1   ' E pin on B3
Declare LCD_Interface 4     ' Interface method is 4 bit

Declare CCP1_Pin PORTC.2
Declare CCP2_Pin PORTC.1
'------------Variables-------------
 Dim DATO[9]   As   Byte         'arreglo para recibir caracteres del puerto serie
 Dim NUM[9]    As   Byte         'arreglo para interpretar numeros del RS232
 Dim I As Byte
 Dim INDICE    As   Byte         'variable para el index de posicion de datos
 Dim DATOE     As    Byte        'variable para caracter recibido en rs232
 Dim DATOACUM As Dword           'V_ para numero recibido por el RS232
 Dim DATOS As Word
 Dim   mot_pwr  As    Dword      ' set point de posicion
 Dim   recu_pos As    Dword      'para recuperar posicion
 Dim   Upos     As    Word       ' ultima posicion
 Dim   vel      As    Word       'velocidad del motor en pwm
 Dim   pot_val  As    Byte        
 Dim   Posicion As    Word       'posicion real en 16 bits
 Dim   Posicion2 As   Word       'posicion real en 32 bits
 Dim   posH     As    Byte
 Dim   posL     As    Byte
 Dim   posHtem  As    Byte   
 Dim   FreMot  As     Word       'frecuencia para el pwm "motor"
 Dim   a       As     Float      'parametro proporcional del PID
 Dim   b       As     Float      'parametro integral del PID
 Dim   c       As     Float      'parametro derivativo del PID
 Dim   rt      As     Float
 Dim   eT      As     Float
 Dim   iT      As     Float
 Dim   dT2     As     Float
 Dim   yT      As     Dword
 Dim   uT      As     Float      'salida del PID en PWM
 Dim   iT0     As     Float
 Dim   eT0     As     Float
 Dim   vmax    As     Byte       'velocidad maxima del motor en PWM
 Dim   vmin    As     Byte       'velocidad minima del motor en PWM
 Dim   Pantalla As    Byte   
 Dim   sentido2 As    Byte	 
 Dim   Activo   As    Byte
'--------------------
    ANSEL0 = %00000001       'configuracion de E/S analogicas
    ANSEL1 = %00000000            
    TRISA = %00011111        'configuracion de entradas digitales para el encoder
    LATA  = %00000000           
    TRISB = %00000000           
    TRISC = %10010000      
    TRISD = %00000000    
    QEICON = %10011000       'conteo X4, se resetea en 65535 (desborda), sin INDEX     
    PORTC.0 = 0 '1                 
    PORTC.1 = 0 
    PORTD.0 =1                 
Print Cls
Print At 1,1," CARGANDO"
Print At 2,1," PARAMETROS"

DelayMS 10
PORTD.0=0
    
    FreMot = 16000                  'frecuencia para el hpwm
    PORTC.0 = 0                 
    PORTC.3 = 0                           
    Upos=1                                                         
    Posicion= 0                 'variable posicion real       
    Posicion2=0
    POSCNTH = 156                 'para tener un 40000 en posicion
    POSCNTL = 64         
    vmin= 75                   'pwm minimo para el motor
    vmax= 180                   'pwm maximo para el motor
    iT0= 0                     'variable para calulo de termino derivarivo
    eT0= 0                      'variable para calculo del error
    a = 0.50                        'parametro proporcional
    b = 0.0009                       'parametro integral
    c = 0.050                        'parametro derivativo
INDICE=0
DATOE=0
DATOACUM=0
mot_pwr = 40000     'se le asigna una posicion de inicio.
recu_pos=40000
Pantalla = 1        'pantalla de inicio de LCD
sentido2= 0
Activo=0
'*********************************************************************
'********************PROGRAMA PRINCIPAL********************************
'*********************************************************************             
lop:                                                                                           
    GoSub CalPos                'ir a calcular la posicion actual
    
    GoSub calvel               'calcular PWM para el motor
   
    If mot_pwr = yT Then  'se borra el acumulado del error
        iT0=0
        eT0=0
        sentido2 =0
        HPWM 1, 0, FreMot     'no sale PWM por CCP1
        HPWM 2, 0, FreMot       'por CCP2 no sale nada
    EndIf  
   
    If mot_pwr > yT Then  'si set point es mayor que posicion actual                         
        HPWM 1, vel, FreMot     'sale PWM por CCP1
        HPWM 2, 0, FreMot       'por CCP2 no sale nada
    ElseIf mot_pwr < yT Then 'en caso contrario posicion actual > set point
        HPWM 2, vel, FreMot     'no sale nada por CCP1  
        HPWM 1, 0, FreMot       'sale pwm por CCP2
    EndIf                             
   
   ' GoSub lcd                   'muestra informacion en LCD

    GoTo lop                      
 
 End  
' ***********************************************************************************
'*****************FIN PROGRAMA PRINCIPAL*********************************************
'************************************************************************************    
lcd:                            'sub que muestra en lcd
If Pantalla = 1 Then
    Print At 1,1, "p=",Dec5 mot_pwr," v=", Dec3 vel'Dec3 vel  
    Print At 2,1, "R=",Dec5 Posicion ," e=", Dec1 eT
    'HSerOut["pos=", dec yt, "*",13]
    'delayms 10
ElseIf Pantalla = 2 Then
    Print At 1,1, "P",Dec4 a," I", Dec4 b         'Dec3 vel  
    Print At 2,1, "D",Dec4 c ," e=", Dec1 eT
ElseIf Pantalla = 3 Then
    Print At 1,1, "p=",Dec5 mot_pwr," P", Dec3 a'Dec3 vel  
    Print At 2,1, "R=",Dec5 Posicion ," I", Dec4 b
EndIf                                                                                             
Return   
'********************************************************************************** 
CalPos:                        'sub para calcular posicion
    posH = POSCNTH             'registros de posicion del modulo
    posL = POSCNTL             'QEI del micro 
    posHtem = POSCNTH
    If posH - posHtem = 0 Then GoTo Listo
    posH = POSCNTH
    posL = POSCNTL    
Listo:    
    Posicion = 256*posH + posL 'se convierte en 16 bit la pos
    If Desbordamiento = 1  Then
        Desbordamiento= 0
        
        If sentido2 = 1 Then
            Posicion2 =Posicion2 + 1  'SE CONVIERTE EN 32 BITS
            'sentido2 =0
        ElseIf sentido2 =2 Then       
            Posicion2 =Posicion2 - 1
            'sentido2 =0
        EndIf
    EndIf
    yT= 65536 * Posicion2 + Posicion
    Return  
'*******************************************************************************    
'****************************P*I*D**********************************************        
calvel:                  'CALCULO DEL PWM CON PID
    eT = Abs(mot_pwr - yT)'calculo del error
    eT = eT * (360/2000)  'ESCALAMOS: 360 grados es a 2000 pulsos del encoder
    iT = b*eT + iT0       'calculo de valor integral (magnitud del error)
    dT2 = c * (eT - eT0)  'calculo del valor derivativo (tiempo de respuesta)
    uT = iT + a * eT 
    uT = uT + dT2         'valor del PID
    
    If uT> vmax Then      'si la salida del PID es mayor que el valor de PWM
        uT = vmax         'que puedo mandar asignale el valor 255
    Else
        If uT< vmin Then uT=vmin  'PWM minimo que quiero enviar
    EndIf
    vel=uT                'velocidad del motor en PWM
    iT0=iT 
    eT0=eT   
    Return      
    
    
'*********************interrupcion PUERTO SERIE ********************************    
serie:
Context Save
HSerIn [DATOE] ' recibo el caracter de la pc por el rs232
RCSTA.4=0
RCSTA.4=1
 
If DATOE=="y" Then   ' lo que llega por el RS232 es para este micro
   INDICE=0          'EN UN MICRO AQUI LE PONGO "X" Y EN OTRO LE PONGO "Y"
   DelayMS 1
ElseIf DATOE=="x" Or DATOE=="z"  Then 'lo que llega por el RS232 no es
    INDICE=0                           'para este micro
    recu_pos = mot_pwr                 'almaceno la posicion actual
EndIf    

 DATO[INDICE]=DATOE       'se almacena el dato en el arreglo
 INDICE=INDICE+1          'para el siguiente dato incremento el indice

If DATOE== "*"  Then  ' cuando del PC llaga un "*" interpreto el numero que recibi

  If DATO[0]=="y" Then    'TRABAJA ESTE MICRO y no otros en la red
     INDICE=0
     For I=2 To 7      ' guardo los datos en un arreglo
        Select Case DATO[I] 'dato que recibi
            Case 48                 ' es un cero?
                NUM[I]=0           
            Case 49                 ' es un uno?
                NUM[I]=1
            Case 50                 ' es un dos?
                NUM[I]=2
            Case 51                 'creo que ya entendieron....
                NUM[I]=3
            Case 52
                NUM[I]=4
            Case 53
                NUM[I]=5
            Case 54
                NUM[I]=6
            Case 55
                NUM[I]=7
            Case 56
                NUM[I]=8
            Case 57                   ' es un nueve?
                NUM[I]=9
            Case Else    'CUALQUIER OTRO CARACTER LO TOMA COMO CERO "O"
                NUM[I]=0
        End Select 
     Next I
     'aqui determino que numero me enviaron por el PC
     'DATOACUM1=NUM[7] + NUM[6]*10 + NUM[5]*100 + NUM[4]*1000 + NUM[3]*10000 
     DATOACUM = NUM[7]  + NUM[6]*10 
     DATOACUM=DATOACUM  + NUM[5]*100 
     DATOACUM =DATOACUM + NUM[4]*1000
     DATOACUM=DATOACUM  + NUM[3]*10000 
     DATOACUM=DATOACUM  + NUM[2]*100000
    Select Case DATO[1]
        Case "p"                 ' recibio un cambio de posicion
            mot_pwr=DATOACUM
            If mot_pwr > yT Then
                sentido2 = 1
            Else
                sentido2 = 2
            EndIf
        Case "V"                  'recibio un cambio de velocidad maxima
            If DATOACUM > vmin Then
                If DATOACUM > 255 Then
                    vmax = 255
                Else
                    vmax = DATOACUM
                End If 
            EndIf    
         Case "v"                  'recibio un cambio de velocidad minima
            If DATOACUM < vmax Then
                If DATOACUM < 20 Then
                    vmin = 20
                ElseIf DATOACUM > 200 Then
                    vmin =200
                Else
                    vmin = DATOACUM
                End If  
            EndIf                'recibio un cambio de parametro proporcional
         Case "P"
            a = DATOACUM / 10000
         Case "I"                'recibio un cambio de parametro integral
            b = DATOACUM / 10000
         Case "D"                'recibio un cambio de parametro derivativo
            c = DATOACUM / 10000
         Case "q"                'recibio un cambio de pantalla a mostrar en LCD
            If DATO[2]="1" Then
                Pantalla=1
            ElseIf DATO[2]="2" Then
                Pantalla=2
            ElseIf DATO[2]="3" Then
                Pantalla=3
            EndIf
         Case "x"               'envia la posicion actual por rs232
             HSerOut[Dec6 yT]
             DelayMS 10
    End Select    
    
    EndIf       
    
    If DATO[0]=="x" Then      'NO TRABAJA ESTE MICRO EN LA RED 
         RCSTA.4=0
        RCSTA.4=1
        INDICE=0
        mot_pwr=recu_pos     ' para que mantenga la posicion
    EndIf
EndIf

If DATO[0]=="y" Then
  HSerOut[DATOE]             'envio lo que recibo....nomas...
EndIf

INTCON = %11000000
Context Restore

mañana les explico lo de cinemática inversa...
 
Excelente proyecto... quedamos a la espera de más información, felicitaciones!
Quisiera aprovechar este espacio para preguntar.... como siempre... si alguien puede orientarme... han llegado a mis manos 2 displeys nokia 1100 y me ha picado la curiosidad que cómo activarlos, lo curioso es que todo lo que he buscado está hecho en C o CCS, no entiendo bien el lenguaje, además son códigos extensos que no logro descifrar con claridad, en fin, me gustaría poder simular en proteus un mensaje básico y creo que el documento adjunto es un buen punto de partida, pueden ayudarme?

Yo haria la traduccion asi:
Código:
Trisb=0
Sclk var portb.4
sda  var Portb.5
cs   var portb.6
rst  var portb.7
i    var word
cd   var bit
C    Var Byte

Gosub Lcd_init

Main:
 cd=0:c=$40:gosub Lcd_write    'Y=0
 cd=0:c=$B0:gosub Lcd_write

 cd=0:c=$10:gosub Lcd_write    'X=0
 cd=0:c=$00:gosub Lcd_write
Goto Main

Lcd_Init:
 cs = 0
 rst = 0
 pause 30
 rst = 1
 cd=0:c=$20:gosub Lcd_write
 cd=0:c=$90:gosub Lcd_write
 cd=0:c=$A4:gosub Lcd_write
 cd=0:c=$2F:gosub Lcd_write
 cd=0:c=$40:gosub Lcd_write
 cd=0:c=$B0:gosub Lcd_write
 cd=0:c=$10:gosub Lcd_write
 cd=0:c=$00:gosub Lcd_write
 cd=0:c=$C8:gosub Lcd_write
 cd=0:c=$A1:gosub Lcd_write
 cd=0:c=$AC:gosub Lcd_write
 cd=0:c=$07:gosub Lcd_write
 cd=0:c=$F9:gosub Lcd_write
 cd=0:c=$AF:gosub Lcd_write
 gosub Lcd_Clear
return
 

Lcd_Write:
 sclk = 0
 sda = cd
 sclk = 1
 for i=0 to 7
  sclk = 0
  if c.7 then
   sda = 1
  else
   sda = 0
  endif 
  sclk = 1 
  c=c << 1
 Next
REturn  

Lcd_Clear:
 cd=0:c=$10:gosub Lcd_write
 cd=0:c=$00:gosub Lcd_write
 cd=0:c=$B0:gosub Lcd_write
 For I=0 to 863
  cd=1:c=$00:gosub Lcd_write
 next  
REturn



Quizas tenga un error por ahi pero como no tengo un lcd nokia para probarlo:rolleyes:
comentanos si no te funciona.

obviamente le faltan los fuses y todos los demas menesteres.
 
Última edición:
Hola "LaElectronicaMeOdia",

Primero quiero darte las gracias por tu ayuda, manejo muy poco de lenguaje C y nunca hubiera podido descifrar ese código, ahora la simulación parece funcionar en lo que corresponde al arranque y limpieza de la pantalla. Adjunto la simulación con las librerías que San Google me dió y que me permiten la simulación de la pantalla para que, a quien pueda interesarle, de rienda suelta a su creatividad, yo ahora voy a tratar de sacar lo básico, el "Hola mundo".
 

Adjuntos

  • pic 16f628 con displey Nokia 1100.rar
    319.3 KB · Visitas: 107
Cinemática inversa
aquí les dejo este pequeño manualito que les acabo de hacer
donde les explico la cinemática inversa del robot que les
mostré en los vídeos anteriores
denme tiempo y les pongo un vídeo utilizando este manual
y la parte de simulación en VB6
también les dejo un simulador hecho en VB6 (.exe) donde
se utiliza esta cinemática para calcular los ángulos
solo le dan un punto en el plano y mover
 

Adjuntos

  • cinematica inversa 2D_2.pdf
    248.5 KB · Visitas: 169
  • aucROBOR2GDL.rar
    4.9 KB · Visitas: 121
Última edición:
Atrás
Arriba