Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?
05/07/2015 #2921


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
06/07/2015 #2922

Avatar de torres.electronico

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... no funciono y dbe de ser bobo el error, pero no lo veo

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 y es gracias a un ejemplo de Ricardo


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 ), se lo agradecere...saludos
06/07/2015 #2923
Moderador

Avatar de D@rkbytes

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:
Código 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      JustDerCanales 0,1VRefAN3

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.
06/07/2015 #2924

Avatar de torres.electronico

no me cierra algo y debe de ser por eso que estoy trabado como puerta con cerrojo o burro empacado
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 ... 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


Voy a jugar con tu ejemplo para ver si puedo hacer magia En este caso, podria usar referencia 5Vcc, verdad?
Imágenes Adjuntas
Tipo de Archivo: jpg In_Out_ASC712.JPG (37,7 KB (Kilobytes), 272 visitas)
06/07/2015 #2925
Moderador

Avatar de D@rkbytes

torres.electronico dijo: Ver Mensaje
¿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.
torres.electronico dijo: Ver Mensaje
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.
06/07/2015 #2926

Avatar de torres.electronico

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
07/07/2015 #2927

Avatar de torres.electronico

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... Toy muy errado? acepto un cachetazo
07/07/2015 #2928
Moderador

Avatar de D@rkbytes

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.
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?
Imágenes Adjuntas
Tipo de Archivo: jpg Gráfica Sensed Current.jpg (99,6 KB (Kilobytes), 272 visitas)
07/07/2015 #2929

Avatar de torres.electronico

D@rkbytes dijo: Ver Mensaje
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.
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?
Lo estoy por encargar porque me pareció un muy buen precio (99$, o sea, 10 dolares aproximadamente) en cuanto a funcionalidad, tamaño y para la infinidad de proyectos que lo podría meter (si es que puedo llegar a entender como usarlo )

Igualmente, por lo que vi, hay algo de desinformación al respecto.
La hoja de datos dice una cosa, en varios foros y google otras tantas y más o menos, sólo concuerda con la hoja de datos de los valores del sensor si le coloco una corriente variable.

Estaba justamente perdiendo el tiempo en una tabla que pensé que era la solución.
Suena gracioso, pero estaba en el arenero escribiendo una desparramada y de repente me pasó algo por la cabeza y arranqué a escribir unas lineas, pero después me di cuenta que seguía co la misma idea del principio y tendría el mismo problema.

---------- Actualizado después de 3 horas ----------

No entiendo dónde estoy aplicando mal mis matemáticas.
El primer error que noté, es que si entran 5V (4,98Vcc), en el micro se lee ValorADC=1003 como máximo y en 0V=511
Ahí seguro le estoy errando en la configuración del puerto.

El tema está en que estoy viendo de hacerlo trabajar de esta manera y no me cierra.
Como tengo que trabajar entre 512 y 1024, lo que hago es restar ambos y lo divido por la cantidad de pasos (30Amp=30pasos), dándome como resultado la supuesta sensibilidad, o dicho en otra forma, la tensión que varía entre paso y paso (1,71v)

(1024 - 512)=513 / 30 =17.1 = 1,71v por Amp

Hasta acá en una hoja con lápiz cuaja la idea:

(ValorADC - Offset)/ sensibilidad * pasos

Pero llevarlo al plano real está siendo todo un fastidio. No me da para nada el valor que tendría que darme.


Código:
DEFINE OSC 4
@ DEVICE pic16F877A
@ DEVICE pic16F877A, WDT_OFF
@ DEVICE pic16F877A, PWRT_On
@ DEVICE pic16F877A, PROTECT_OFF

DEFINE LCD_DREG      PORTD    
DEFINE LCD_DBIT      4        
DEFINE LCD_RSREG  PORTD    
DEFINE LCD_RSBIT  2    
DEFINE LCD_EREG      PORTD    
DEFINE LCD_EBIT   3        
DEFINE LCD_BITS      4    
DEFINE LCD_LINES  2

Define    ADC_BITS    10             ' Establece el número de bits en el resultado
Define    ADC_CLOCK    3             ' Ajuste el reloj de origen (rc=3)
Define    ADC_SAMPLEUS    50          ' Establezca el tiempo de muestreo en uS 

INTCON=%10100001           
TMR0=0 
T2CON = %00000110
PR2=124     

CMCON=7

ADCON1=%10000010
TRISA=%000001
TRISB=%11111111
TRISC=%01111011
TRISD=%00000000     


AUX var word 
AMP var word
ValorADC var word
Offset con 512               

;ON INTERRUPT GoTo ATENCION
;********************************************************************
;Configuro como valor offset 511 que representa supuestamente el valor 2.49V-0A
;para sacar la escala, resto la lecura maxima con la lectura minima y la divido
;por los pasos
; (1024 - 512)=513 / 30 =17.1 = 1,71v por Amp  
;Supuestamente entonces, para hacer la lectura tendria que:
;(ValorADC - Offset)/ sensibilidad * pasos 
; y no me da para nada... #@¬€<*n¨*^[]&¬¬!!!!!! 
;********************************************************************
LCDOUT $fe,1
Inicio:

pause 200
aDCIN 0, ValorADC
AMP = (ValorADC - offset) * 17 /513
AUX = (ValorADC - Offset) /513         ;una prueba alternativa que tampoco me dá


LCDOUT $FE,$80,"A=",dec AMP,".",dec1 amp," ADC=",dec ValorADC
LCDOUT $FE,$C0,"A=",dec Aux,".",dec1 aux
goto inicio


End

;----------------------------------------------------------------
;----------------------------------------------------------------

;*****************************************************************
;++++++++++++++++++++++++ INTERRUPCION +++++++++++++++++++++++++++
;*****************************************************************

DISABLE
ATENCION:
        

INTCON.2=0    
RESUME
ENABLE

END
;*****************************************************************
;*****************************************************************

La salida es lineal, al parecer.
08/07/2015 #2930
Moderador

Avatar de D@rkbytes

Cada paso del ADC a 10 bits con VRef+ en 5 V y VRef- en 0V, es cada 0.00488 V (4.88 mV.)

Pero si el ACS712 con 0 Amperes tiene 2.5 V como salida, entonces la lectura del ADC será de 512. (La mitad)
Eso se tendrá que descontar para que con 2.5 V, la lectura en 0 Amperes muestre 0.

Prueba así, pero recuerda que el valor mínimo de entrada al ADC son 2.5 V y el máximo 4.5 V.
Código PHP:
Declaración de variables:
Valor_ADC   Var Word
Amperes     
Var Byte

Inicio
:
    
Define ADC_BITS 10      10 bits de resolución
    ADCON1 
= %10000101      JustDerCanales 0,1VRefAN3

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

Programa:
    
ADCIn 0,Valor_ADC
    Amperes 
= (30 * (Valor_ADC 512) / 439) ; 439 Valor por paso en 4.5 V. (0.00439 V.)
    
LCDOut $FE,$C4,Dec2 Amperes," Amps."
    
GoTo    Programa


    End 
Este programa usa el pin RA3 (AN3/VRef+) en donde deberás establecer la tensión de referencia.
Coloca un potenciómetro y fija un valor alrededor de 4.88 V para realizar la prueba.

Algo así: ACS712-30A Test.jpg
09/07/2015 #2931

Avatar de torres.electronico

Con la referencia mejoro mucho, tenes razon; Ahí logre hacer algo que se aproxima un poquito mas, pero estoy viendo que lo voy a tener que hacer fisicamente si o si para ver si no es la libreria de proteus lo que no me cierra con exactitud (estoy dudando de los pasos)...

Código:
DEFINE OSC 4
@ DEVICE pic16F877A
@ DEVICE pic16F877A, WDT_OFF
@ DEVICE pic16F877A, PWRT_On
@ DEVICE pic16F877A, PROTECT_OFF

DEFINE LCD_DREG      PORTD    
DEFINE LCD_DBIT      4        
DEFINE LCD_RSREG  PORTD    
DEFINE LCD_RSBIT  2    
DEFINE LCD_EREG      PORTD    
DEFINE LCD_EBIT   3        
DEFINE LCD_BITS      4    
DEFINE LCD_LINES  2


INTCON=%10100001           
TMR0=0 
T2CON = %00000110
PR2=124     

CMCON=7
TRISB=%11111111
TRISC=%01111011
TRISD=%00000000     
PARAR         VAR PORTB.3
BOTON_MAS     VAR PORTB.4
BOTON_MENOS   VAR PORTB.5
BOTON_ENTER    VAR PORTB.6
BOTON_MENU     VAR PORTB.7

Valor_ADC   Var Word
Amperes     Var Byte 
AMP var word              
Mamp var word
;ON INTERRUPT GoTo ATENCION

Inicio:
Define ADC_BITS 10      ; 10 bits de resolución
ADCON1 = %10000101      ; Just. Der. Canales 0,1, VRef+ AN3
    
Programa1:
    LCDOut $FE,1
    ADCIn 0,Valor_ADC
    Amp = (30 * (Valor_ADC - 512) / 439) 
    gosub limites       
    LCDOut $FE,$80,Dec Amp,".",dec1 mamp," Amps"
    LCDOut $FE,$C0, dec valor_adc 
    pause 100
    GoTo Programa1      

Limites:
    if amp > 0 and amp < 1023 then   ; anti desborde
    amp = Amp-1
    mamp = amp>> 1 +1 
    if Valor_ADC < 512 then
    mAmp = 0
    endif
    endif
    if Valor_ADC < 512 then         ;para ignorar valores negativos
    Amp = 0
    endif
    if Valor_ADC > 1022 then        ;para limitar el maximo
    Amp = 30
    endif
     
    return

End

;----------------------------------------------------------------
;----------------------------------------------------------------

;*****************************************************************
;++++++++++++++++++++++++ INTERRUPCION +++++++++++++++++++++++++++
;*****************************************************************

DISABLE
ATENCION:
        

INTCON.2=0    
RESUME
ENABLE

END
;*****************************************************************
;*****************************************************************
si no puedo sacarle un mejor margen a los mA... tendre que hacer una tabla al parecer
14/07/2015 #2932

Avatar de torres.electronico

acá logre mejorarlo un poco sin la referencia de tension ...

Código:
DEFINE OSC 4
@ DEVICE pic16F877A
@ DEVICE pic16F877A, WDT_OFF
@ DEVICE pic16F877A, PWRT_On
@ DEVICE pic16F877A, PROTECT_OFF

DEFINE LCD_DREG      PORTD    
DEFINE LCD_DBIT      4        
DEFINE LCD_RSREG  PORTD    
DEFINE LCD_RSBIT  2    
DEFINE LCD_EREG      PORTD    
DEFINE LCD_EBIT   3        
DEFINE LCD_BITS      4    
DEFINE LCD_LINES  2
;INTCON=%10100001           
;TMR0=0 
;T2CON = %00000110
;PR2=124     
;CMCON=7
DEFINE    ADC_BITS    10        
DEFINE    ADC_CLOCK    3        
DEFINE    ADC_SAMPLEUS    50
ADCON1=%10001110 
TRISB=%11111111
TRISC=%01111011
TRISD=%00000000     

PARAR         VAR PORTB.3
BOTON_MAS     VAR PORTB.4
BOTON_MENOS   VAR PORTB.5
BOTON_ENTER    VAR PORTB.6
BOTON_MENU     VAR PORTB.7

Valor_ADC   Var Word
AMP         var word              
mA          var byte
;ON INTERRUPT GoTo ATENCION

'------------------------------------------------------------------------------- 

Inicio:
   LCDOut $FE,1
   ADCIN 0,valor_adc  
   LCDOut $FE,$80,"ADC =",dec valor_adc
   amp=((valor_adc-511)*100)/139   ;511 es el punto minimo y 139 el valor del paso en mA
   mA=amp//10
   amp=amp/10
   LCDOUT $FE,$C0,"Amp=",dec amp,",",dec mA
   pause 100
   goto inicio 

End

;----------------------------------------------------------------
;----------------------------------------------------------------

;*****************************************************************
;++++++++++++++++++++++++ INTERRUPCION +++++++++++++++++++++++++++
;*****************************************************************

DISABLE
ATENCION:
        

INTCON.2=0    
RESUME
ENABLE

END
;*****************************************************************
;*****************************************************************


lo que no me cierra, es que para que el programa me de un valor aproximado con esa libreria, eh tenido que colocar en el valor del paso el 139 (el doble y un poco mas de los 66mV que dice la hoja de datos)... asi que tendre que esperar a tener el sensor en mis manos para ver realmente de cuanto es el salto.
Imágenes Adjuntas
Tipo de Archivo: jpg ASC712_16F877A.JPG (78,4 KB (Kilobytes), 253 visitas)
23/07/2015 #2933


papirrin dijo: Ver Mensaje
No cuando inicia asigna el codigo ascii a eprom1 como lo tienes, el que parece ser 48 necesitas quitar las comillas asi:
Código:
n1 var byte
eprom1 var byte

eprom1=0
'aqui siiii... eprom1 vale 0
PAUSE 100
'no tiene sentido que antes declares a eprom1=0 si haces la lectura de la eeprom
READ 0, eprom1
'aqui si no se ha grabado la eeprom con n1 , eprom1 vale 255
IF eprom1=255 THEN grabar_clave
GOTO Bienvenida

grabar_clave:
??? aqui a n1 nunca le dices cuanto vale?
Write 0, n1
pause 10

' debes poner una pausa de 10ms para que complete la grabacion
siempre entra al iniciar porque la memoria por defecto esta en 255 (FF)
Hola amigo. muchas gracias por esta aclaración. Si yo hubiese sabido que la eprom por defecto al inicarse vale 255 (FF) no hubiera preguntado. Ahora todo está claro. Es más. teniendo la teoría que me dijiste, veo (e hice pruebas) que no importa que valor tiene eprom1, por que siempre al iniciarse se escribirá 255 y por lo tanto se ejecutara´"grabar_clave". Luego ya no valdrá 255 y se ejecutará "Bienvenido". Tambien gracias por el dato de darle una pausa de 10ms después del WRITE. Saludos.
24/07/2015 #2934

Avatar de papirrin

Ya te comente que a la eeprom se le asigna un valor "por defecto" con la instruccion DATA busca en la ayuda del pbp como se usa
17/08/2015 #2935


como es el codigo de interrupcion por timer en el pic 18f4550 ya vengo buscando horas en internet pero no hay mucho material del tema sino que hay mucho info de interrupcion externa
17/08/2015 #2936
Moderador

Avatar de D@rkbytes

PANC dijo: Ver Mensaje
¿Cómo es el código de interrupción por timer en el PIC18F4550?
¿De cuál timer? El PIC18F4550 tiene 4 timers, 1 de 8 bits y 3 de 16 bits.
El código también depende de lo que quieras hacer.
18/08/2015 #2937

Avatar de torres.electronico

D@rkbytes dijo: Ver Mensaje
¿De cuál timer? El PIC18F4550 tiene 4 timers, 1 de 8 bits y 3 de 16 bits.
El código también depende de lo que quieras hacer.
Interesante. Cómo se nota que no toqué la hoja de datos.
Ahora implemento el buscador de la página para ver si encuentro más información del 18F4550.
Estoy dejando de lado los 16F876 y 16F877 para adentrarme a esta nueva familia con USB, ya que me di cuenta que varios fuses que usaba anteriormente, no me funcionan con el 18F2550/4550
18/08/2015 #2938
Moderador

Avatar de D@rkbytes

torres.electronico dijo: Ver Mensaje
Estoy dejando de lado los 16F876 y 16F877 para adentrarme a esta nueva familia con USB, ya que me di cuenta que varios fuses que usaba anteriormente, no me funcionan con el 18F2550/4550
Así es. Los fuses de la palabra de configuración para los PIC18F2550/4550, son diferentes a los PIC16.
Sobre todo por la configuración del prescaler, aunque algunos PIC de nueva generación como los PIC12F18XX y PIC16F18XX, también lo tienen.
No para el uso del módulo USB con oscilador a cristal, sino para elevar la frecuencia del oscilador interno.

Otra cosa a tener en cuenta, es que usan dos líneas o más para la palabra de configuración.
19/08/2015 #2939

Avatar de torres.electronico

si, tenes razon... practicamente estoy re-arrancando de cero por que son similares, pero iguales....
lo poco que hice, me base en fuses de ejemplo y no preste atencion... vamos a ver si me pongo al dia relativamente rapido, por que tengo varias cositas para hacer y me esta gustando bastante este micro. Saludos y veremos con que dolor de cabezo me vuelvo
29/08/2015 #2940


Hola, saludos
hace unos meses atras D@rkbytes me ayudo con un contador ascendente, descendente,de 1 a 6 y viceversa, a partir de ahi logre hacerle unas pequeñas modificaciones a mi gusto, lo que no he podido lograr es hacer que muestre un 0 si le pongo un 0 en el pin RA2 del pic 16f84A independientemente del numero en que este la cuenta, no logro dar la instruccion correcta, pido el favor alguien me ayude con esto y disculpen por haber solicitado ayuda en este tema ya que asm desde cero hace 6 meses nadie escribe, adjunto archivos el .bas que he manipulado y el original sin modificacion, Gracias.
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2016, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.