desktop

Curso de programación de PIC en PICBasic Pro

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
Veo que usas el canal 1, pero en el código sólo estás estableciendo como entrada RA0.
Por lo tanto, RA1 quedará funcionando como salida.
Elimina la instrucción TRISA = 1 para dejar el puerto A como entradas. (Por defecto)

Si el sensor mide hasta 30 amperes y se obtiene 1 ampere por cada 0.066 V, entonces...
0.066 * 30 = 1.98 V.
30 Amperes será tu valor de lectura máximo y 1.98 V será el voltaje de entrada máximo al conversor AD.

Aquí conviene usar el voltaje de referencia VRef+ para establecer un limite y poder realizar un ajuste.

Mira este código de ejemplo para que lo entiendas:
PHP:
;*******************************************************************************
@ Device PIC16F877A    ; Microcontrolador utilizado
; Palabra de configuración:
@ Device XT_OSC,WDT_OFF,PWRT_ON,LVP_OFF
;*******************************************************************************
; Definición de pines para la pantalla.
Define LCD_DREG PORTD        ; Puerto de datos.
Define LCD_DBIT     4        ; Bit de inicio de datos.
Define LCD_RSREG PORTD        ; Puerto de RS (Register Select)
Define LCD_RSBIT    3        ; Pin para RS
Define LCD_EREG PORTD        ; Puerto de E (Enable)
Define LCD_EBIT     2        ; Pin para E

; Declaración de variables:
Valor_ADC   Var Word
Amperes     Var Byte

Inicio:
    Define ADC_BITS 10      ; 10 bits de resolución
    ADCON1 = %10000101      ; Just. Der. Canales 0,1, VRef+ AN3

Inicia_LCD:
    LCDOut $FE,$83,"AMPERIMETRO"

Programa:
    ADCIn 0,Valor_ADC
    Amperes = ((30 * Valor_ADC) / 1024)
    LCDOut $FE,$C4,Dec2 Amperes," Amps."
    GoTo    Programa


    End
El voltaje de referencia que debe ser de 1.98 V, lo puedes obtener con un CI TL431 y un potenciómetro como divisor de tensión.
 
:unsure: no me cierra algo y debe de ser por eso que estoy trabado como puerta con cerrojo o burro empacado :LOL:
por que implementas 0.066 (uV o mV?) ... yo implemente0.66 ... por ahí veo que arranca parte de mi problema... y el otro gran problema que tengo, es que yo me encerre con lo que dice la hoja de dato, que la salida es de 0-5Vcc, o sea, 5Vcc para 30Amp y 2,3Vcc para 0Amp y 0Vcc para -30Amp
Voy a quedarme un buen rato interpretando tu ejemplo y ver si puedo abrir un poco la mente... que brona cuando me trabo :(
Millon de gracias :aplauso: (y) ... termino y subo resultados ;)

EDIT: me parecia que no me cerraba algo, mirá, esta es la grafica que muestra la curva de la salida segun la corriente que pasa por el hall

In_Out_ASC712.JPG
Voy a jugar con tu ejemplo para ver si puedo hacer magia :) En este caso, podria usar referencia 5Vcc, verdad?
 
Última edición:
¿Por qué implementas 0.066 (uV o mV)?
Yo implementé 0.66. Por ahí veo que arranca parte de mi problema.
Yo sólo tomé como referencia los 66 mV que mencionaste.
La tensión de salida proporcional en el sensor de 30Amp, es de 66mV por cada Ampere.
0.66 V, son 660 mV. y 0.066 V, son 66 mV.

Basándome en eso fue que realicé la fórmula.
Si el voltaje de salida es lineal, no hay problema, pero si no lo es, será necesario realizar una tabla para ir tomando valores.
 
me paree que la slaida no es lineal... o por lo menos eso estoy viendo en proteus... Creo que me voy a inclinar por invertir las siguientes horas en una tabla con lookup como bien vos decis... me voy a quedar pelado, eso ponele la firma jajajajaja Gracias amigazo, ahora veo como arrancar de cero...tendria que borrar todo lo que hice para no perderme, equivocarme y arrancare de cero
 
:unsure: sigo dando vueltas como una calesita por que me di cuenta que yo estoy dividiendo por 1024 (supuestamente 5Vcc), siendo que el sensor la señal es de 2.5 a 5Vcc para corrientes positivas de 0 a 30Amp... si yo lo sigo interpretando de la misma manera que antes, si no mal interpreto, estaria metiendo todos los valores enteros dentro del 1024, cuando justamente los valores mas bajos corresponderian a 0-2.4Vcc, o sea, corriente negativa (ejemplo -30Amp)... Como yo necesito solo la parte positiva, tengo que ver como separar las lecturas mayores a 2.5Vcc y de ahi buscarle la vuelta para la transformacion... :unsure: Toy muy errado? :rolleyes: acepto un cachetazo :LOL:
 
Al ver la siguiente gráfica, me parece que existen más de los 1.98 V que supuestamente se obtendrían al sensar 30 amperes.
Gráfica Sensed Current.jpg
Sensar 0 Amperes está por los 2.5 V, mientras que 30 amperes está casi por los 4.5 V.

¿Ya realizaste pruebas en físico con el sensor para ver que valores arroja?
 
Atrás
Arriba