Curso de programación de PIC en PICBasic Pro

Pues si es extraño que no te funcione físicamente.
Para verificar lo que comentas, monté el circuito en un protoboard y grabé el PIC con la palabra de configuración correcta. (O sea, la que te sugerí)

Tanto en proteus como en el protoboard, funcionan bien.


Te recomiendo que realices un programa simple, como hacer destellar un LED cada 500 ms.
Cuando esté en funcionamiento, quita el cristal y el programa se debe detener.
Si el LED sigue destellando a la misma frecuencia u otra más baja, entonces quiere decir está entrando en funcionamiento el oscilador interno debido al fuse FCMEN y algo sigue mal con tu palabra de configuración.

Nota:
Por lo que mencionas, todo parece indicar que estás grabando el PIC con los fuses erróneos.

Hola buenos dias; Te comento que hice el ejercicio que me recomendaste con un led y el resultado fue el siguiente:

Con el archivo .INC original y los fuses que inicialmente le habia colocado, el led prendió normalmente haciendo su rutina de prendido y apagado cada 500 ms; al quitarle el cristal como me indicaste el led se apagó.

Con el archivo .INC modificado y los fuses que me indicaste le colocara, el led no prendió.

Que podria ser? o sera el pic? lo raro es que pedí prestado otro pic 18f2550 y sucede lomismo.
gracias
 
Es muy extraño lo que te sucede. Si yo compilo con los fuses por defecto y un cristal de 4 MHz, el LED destella más rápido, como a unos 250 ms.
En cambio, usando los fuses para configuración XT sin USB, el LED destella normalmente a 500 ms.

Este es el sencillo programa de prueba que usé.
Código:
[B]Asm[/B]
[COLOR=Green]    Config FOSC = XT_XT, WDT = OFF, PWRT = ON, LVP = OFF
    Config USBDIV = 1, PLLDIV = 1[/COLOR]
[B]EndAsm[/B]

Inicio:
    [B]Define[/B] OSC 4
    ADCON1 = 15
    
    TRISB.7 = 0
    
Programa:
    LATB.7 = 1
    [B]Pause[/B] 500
    LATB.7 = 0
    [B]Pause[/B] 500
    
    [B]GoTo[/B] Programa
    
    [B]End[/B]
Obviamente, para usar los fuses por defecto del archivo 18F2550.INC, comento los del programa y descomento los del archivo, y para usar los fuses del programa, comento los del archivo y descomento los del programa.

Si haces todo correctamente, deberías tener los mismos resultados que en las pruebas que yo he realizado.
 
Es muy extraño lo que te sucede. Si yo compilo con los fuses por defecto y un cristal de 4 MHz, el LED destella más rápido, como a unos 250 ms.
En cambio, usando los fuses para configuración XT sin USB, el LED destella normalmente a 500 ms.

Este es el sencillo programa de prueba que usé.
Código:
[B]Asm[/B]
[COLOR=Green]    Config FOSC = XT_XT, WDT = OFF, PWRT = ON, LVP = OFF
    Config USBDIV = 1, PLLDIV = 1[/COLOR]
[B]EndAsm[/B]

Inicio:
    [B]Define[/B] OSC 4
    ADCON1 = 15
    
    TRISB.7 = 0
    
Programa:
    LATB.7 = 1
    [B]Pause[/B] 500
    LATB.7 = 0
    [B]Pause[/B] 500
    
    [B]GoTo[/B] Programa
    
    [B]End[/B]
Obviamente, para usar los fuses por defecto del archivo 18F2550.INC, comento los del programa y descomento los del archivo, y para usar los fuses del programa, comento los del archivo y descomento los del programa.

Si haces todo correctamente, deberías tener los mismos resultados que en las pruebas que yo he realizado.

Hola buenos dias, realizaré el ejercicio y te comento. Yo adjunte una foto del menu de fuses que muestra mi programador K150; observaste algo extraño? habrá que cambiarle algún otro dato o está bien? gracias por tu atencon.
 
Lo que puedes hacer, es usar la interrupción externa por RB0, tomar el tiempo con el Timer 0 y en cada transición de la señal, limpiar el Timer y cambiar el flanco de interrupción.
De esta forma puedes medir lo que dura cada transición.
¿Qué tal, D@rkbytes?

Perdón por interrumpir el proyecto que vienen realizando.

Tengo unas dudas sobre como medir el ancho de pulso en alto de x señal (cuadrada con un duty cycle del 50%) que inyecto por el PIN_RB0.

Ya lo intenté con el comando pulsin y todo bien, ahora quiero experimentar con otros dos métodos que leí por la web, que son los siguientes:

1.- Utilizando el Timer0 y la interrupcion RB0 <---- Primero sería este.

2.- Utilizando el modulo CCP con el timer.

Bueno, sinceramente los he utilizado por separado.
He utilizado el timer0 para hacer parpadear un led variando el registro TMR0 y así obtener diferentes temporizaciones con sus respectivos cálculos utilizando la formula. OK.

Y al igual he utilizado la interrupción por RB0, pero todo esto por separado.
Ahora lo que se me complica es como unir la INT/RB0 con el Timer0 en la rutina para medir el ancho de pulso de una señal cuadrada cualquiera, no importa precisión.

O sea, ¿Cuales serían a detalle los pasos a seguir? ¿Alguien tendrá un ejemplo o aportarme?
Algo como empezar en la rutina de interrupción RB0, activando/desactivando el timer0 cambiando de flancos ascendente/descendente, etc.

Cabe mencionar que intenté adaptar un código ccs con resultados fallidos, no me hace ni pio y quiero mejor empezar desde cero.

Bueno, en este pseudo código lo único que hice es configurar todos los registros OPTION_REG e INTCON necesarios (creo) para hacer funcionar esta práctica.

Todos los aportes, ejemplos, comentarios, jalones de oreja, bienvenidos.

Gracias

Anexo pseudo código + proteus.
 

Adjuntos

  • img_02.jpg
    img_02.jpg
    141.8 KB · Visitas: 29
  • ancho de pulso.rar
    19.8 KB · Visitas: 44
Última edición por un moderador:
Yo adjunté una foto del menú de fuses que muestra mi programador K150.
¿Observaste algo extraño? ¿Habrá que cambiarle algún otro dato o está bien?
Lo extraño en ese programador es que ponga HS OSC w/PLL (O sea, Oscilador de alta frecuencia con PLL)
Cuando debería ser: XT used by USB. (En la configuración que se está usando no se usará el módulo USB)

En las pruebas que he realizado lo he grabado con el PICKit 3 y también con el JDM usando WinPic800, obteniendo los mismos resultados.

Los valores de los fuses para las tres aplicaciones son algo diferentes, sin embargo el valor número 1 es el mismo y es el que corresponde al tipo de oscilador.

Éstos son los valores leídos:

Con MicroBrn:
Fuse Value(s) (MicroBrn).jpg

Con WinPic800:
Fuse Value(s) (Winpic800).jpg

Con PICKit 3:
Fuse Value(s) (PICKit 3.jpg

Trata de grabar el PIC con otro programador y verifica su comportamiento.

Tengo unas dudas sobre como medir el ancho de pulso en alto
de x señal (cuadrada con un duty cycle del 50%) que inyecto por el PIN_RB0
O sea, cuales serían a detalle los pasos a seguir. ¿Alguien tendrá un ejemplo o aportarme?

Algo como empezar en la rutina de interrupción RB0, activando/desactivando el timer0
Necesitas seleccionar un rango para el prescaler establecido al Timer 0 usando el registro OPTION_REG.
Lo puedes hacer fijo desde 1:2 <> 1:256, eso depende de la frecuencia de trabajo y la frecuencia que quieras medir. (Ver; ciclos de instrucciones en un PIC.)
Algo más complicado es verificando el desborde del Timer 0 y cambiando el prescaler.

Después, durante el servicio de interrupción por RB0, (Interrupción externa) limpias el Timer 0, realizas un bucle de espera hasta que RB0 cambie de alto a bajo, das un tiempo de reestablecimiento de unos 3 o 10 us, y a continuación lees el valor del Timer 0.
Ese valor será el periodo que tardó el pulso en cambiar de estado.
Si lo requieres, puedes hacer una conversión dividiendo el valor de la lectura por el rango del prescaler.

Saludos.
 
Última edición:
Hola primero un saludo a esta magnifica comunidad.
Le escribo por que tengo una pregunta con respecto al ADC del PIC16F886 y es con respecto a su configuracion estoy usando este ej. de esta pagina la cual dejo en este linc http://mrchunckuee.blogspot.com/2014/08/uso-del-adc-con-pic16f887-encender-leds.html
como en este usan un 16F887 y tengo a mano un 16F886 cambie el puerto a representar para los led la cual lo tengo en el puertoB.

Le explico mi inquietud para que el ADC me trabaje tengo que poner una referencia en RA3/VREF, esto es asi por que eh visto el data del micro para configurar los registros ANSEL,ANSELH,CM1CON0,CM2CON0,etc y no logro hacer que RA3 me funcione como entrada y salida digital.

ADCON1 = %10000000
ADCON0 = %11000001
ANSEL = %00000001
CM1CON0 = 0
CM2CON0 = 0
ANSELH = 0

gracias de ante mano y agradesco sus sugerencia.
 
No entendí bien la pregunta.
Primero dices tener dudas acerca de la configuración del ADC y después mencionas que RA3 no te funciona en modo digital.

Pero mira...
Cualquier canal puede trabajar sin usar una referencia, o como mencionas, sin usar RA3.
El registro ANSEL es para los canales del puerto A y ANSELH para los del puerto B.
Estando ANSEL y ANSELH en 0, todos los pines trabajarán en modo digital y no es necesario configurar los registros CMXCONX.

Entonces, con estar en 0 el bit 3 del registro ANSEL, RA3 será digital I/O
 
Hi D@rkbytes la duda es sobre si es necesario usar el RA3 para el funcionamiento del ADC ya que en la simulacion en proteus solo me funciona de esa manera.
y sobre los registros los tengo de esta manera, la cual por la simulacion surgia mi duda en que si estaban bien configurados.
ADCON1 = %10000000
ADCON0 = %11000001
ANSEL = %00000001
CM1CON0 = 0
CM2CON0 = 0
ANSELH = 0

Gracias por tu pronta respuesta.
 
Si tu voltaje de entrada es de 0 - 5 V. y no necesitas precisión en la lectura, no es necesario usar tensión de referencia.

Mejor adjunta tu proyecto dentro de un archivo comprimido para verlo en detalle.
 
Veo que usas el ADC a 10 bits, pero si el puerto B sólo tiene 8 bits, no tiene caso que lo uses a 10 bits.
Usando el ADC a 10 bits obtendrás una lectura de 1023 cuando el ADC esté al tope.
En cambio, con 8 bits obtendrás una lectura de 255 que se acopla a los 8 bits del puerto B.
Y como al parecer lo que quieres hacer es algo así como un VuMeter, puedes separar más fácilmente los rangos dentro del Select Case y evitas la división.

Mira este simple programa y haz la prueba para que veas que funciona sin usar RA3 como tensión de referencia.
PHP:
;*******************************************************************************
@ Device PIC16F886    ; Microcontrolador utilizado
; Palabra de configuración:
@ Device INTRC_OSC_NOCLKOUT,WDT_OFF,PWRT_ON,BOD_OFF,LVP_OFF,FCMEN_OFF
@ Device2 WRT_OFF,WRT_HALF
;*******************************************************************************
Define OSC 4                ; Frecuencia por defecto del oscilador interno.

Inicio:
    ; Declaración de variables.
    Valor_ADC   Var Byte
;*******************************************************************************
    ; Configuración de registros.    
    TRISB = 0               ; Todo el puerto B como salidas.
    ANSEL = 1               ; Seleccionar AN0
    ANSELH = 0              ; AN8 - AN13 Digital I/O
    PORTB = 0               ; Puerto B en 0
;*******************************************************************************
    Clear                   ; Limpiar RAM (Variables en 0)
   
Programa:
    ADCIn 0,Valor_ADC       ; Leer el canal 0
    PORTB = Valor_ADC       ; Puerto B = Valor de "Valor_ADC"       
    Pause 100               ; Retardo de 100 ms. (Opcional)
    
    GoTo    Programa


    End
Nota que no existen configuraciones extra para el ADC porque se están usando las que el microcontrolador tiene por defecto.
Aquí se obtiene una visualización binaria en el puerto B, ya que sólo es una prueba de funcionamiento para demostrar que sí se puede usar el conversor análogo sin usar RA3.

Suerte.
 
Última edición:
Hi D@rkbytes te comento que en la simulacion anda igual osea necesita el voltaje de referencia, pero pase tu ejemplo a proton ide y funciona sin referencia pero de verdad no se que pasa con el pic basic pro. tambien pienso en que puede ser las versiones que tengo del compilador y micro code.
 
Última edición:
Algo debes estar haciendo mal.
Mira, adjunto el proyecto con la simulación funcionando sin usar RA3.

Si no te funciona, entonces si debes tener algo mal con tus versiones.

Suerte.
 

Adjuntos

  • 16F886 ADC Test.rar
    15.9 KB · Visitas: 51
Hola. ¿Cómo podría sensar el servomotor con un PIC para que cuando esté en funcionamiento el servomotor y uno tiende a frenar, el servo este se detenga?
O sea, que el PIC no le envíe más señal PWM cuando detecta que alguien intenta frenar el eje.

¿Me expliqué bien?
 
Última edición por un moderador:
Tal cual, es una muy buena idea.
Tendría que leer en estado de reposo, en estado "normal de funcionamiento" y guardar esos valores a ojimetro para después hacer una comparaion.



El tema está en que la lectura tendría que ser por muestreo.
O sea, leer un par de veces, sumar las lecturas y dividirla por la cantidad de veces que se sumó.
¿Me equivoco?
 
Última edición por un moderador:
El tema está en que la lectura tendría que ser por muestreo.
O sea, leer un par de veces, sumar las lecturas y dividirla por la cantidad de veces que se sumó.
¿Me equivoco?

yo he echo varios proyectos similares en los que requiero que el motor se pare cuando hay un sobre-consumo, la mayoria de las veces lo hago utilizando los comparadores y su respectiva interrupcion, asi que es instantaneo, osea que no hay tiempos de conversion y el paro sea inmediato pues en ocaciones es tan rapido el aumento de corriente que se alcanza a sobrecalentar el motor o transistor de control antes de que el pic reaccione, pero ahora si que el compañero tendria que dar mas informacion de su proyecto para que se le pueda orientar con mayor presicion.

saludos compañero.
 
Gracias, papirrin. Es una buena idea, lo he probado pero lamentablemente no funciona, es muy probable que me esté confundiendo en algo.

Les cuento el proyecto:
Estoy armando una mano robot, a la cual le envío un dato de la PC al PIC y éste tiene que controlar cada dedo independiente, o sea que cada dedo posee su servo, se debe detener cuando agarre un objeto y cuando sobrecargue al servo.

El problema es que el servo no se detiene cuando sobrecargo al mismo.
Medí la tensión de la resistencia que me indica sobrecarga del servo y ésta me marca entre 1,3 V y 500 mV.

Acá un pedazo del código donde senso el servo del pulgar, y creo que está bien.
Código:
for R=1 to 80                     'si llega a 80 salgo del for osea le doy 80 pulsos al servo
        high SERVO                    'envio un pulso a la señal del servo
        pauseUS 6480                  'demora del pulso 2,7ms 
        ADCIN 0, sensor5              'muestreo ad0 y lo copio a la variable sensor5
        IF SENSOR5>65 then            ' si la tension de r supera 1.27v  entonces
        r=80                          'r =80 asi salgo del for
        endif                         'fin del if
        low SERVO                     'tiempo en bajo de la señal del servo
        pauseUS 41520                 '17,3ms 
    next                              'vuelvo al for
 
Última edición por un moderador:
Estoy intentando hacer algo con un ASC712 y haciendo unas pruebas en proteus, veo que no doy pie con mano...Segun lo que interpreto de la hoja de datos, es que el sensor da una slaida proporcional a la corriente que pasa por el hall... la tension de salida proporcional en el sensor de 30Amp, es de 66mV por cada Amper...

probe con un simple ejemplo y... :rolleyes: no funciono y dbe de ser bobo el error, pero no lo veo :cabezon:

Código:
ADCIN 1, adc
aux = (adc */ 5000)
VCC = (adc */ 5000) >> 2 
amp= aux / 66

LCDOUT $FE,$80,"V:",dec(VCC/1000),".",dec2 VCC, " A:",dec (AMP/10),".",dec2 amp

Lo que intente 1ero es hacer un voltimetro, y segun ese valor, dividirlo por 66 para obtener la corriente... en el segundo reglon, hay una barra que aumenta o decrece segun el dato de entrada... eso si funciona :LOL: y es gracias a un ejemplo de Ricardo

pruebaASC712.JPG
En el archivo ".rar" esta el codigo completo con la simu en proteus... si alguien me puede orientar de como puedo hacer la conversion u darme un cafe para despertarme (hace horas que estoy ensando donde le pifie y nada :cry:), se lo agradecere...saludos
 

Adjuntos

  • sensor de corriente acs712.pdf
    667.8 KB · Visitas: 49
  • pruebaASC712.rar
    624.2 KB · Visitas: 54
Atrás
Arriba