Curso de programación de PIC en PICBasic Pro

este ejemplo es para hacer un joystic, pero si no mueves a lo que se llama los descriptores, y solo generas el codigo con el EasyHID USB Wizard puedes hacer una interfaz en VB Delphi o C++...

aca mas informacion...
 
Hola compañeros estoy de nuevo por acá con un proyecto de practica que estoy realizando, en este caso con unos de mis favoritos el pic12f675, estoy utilizando el ADC0 para la lectura de un sensor de temperatura LM35 y enviar la información por el puerto serial al PC, ya adelante bastante luche para que me enviara correctamente la información vía serial y eso fue por que le faltaba la linea de "DEFINE OSCCAL_1K 1", luego de allí ya tenia todo listo ya tenia el programa que había simulado en el proteus y funciona a la perfección bueno eso creo ya que me da buenas lecturas del sensor a nivel de la simulación, ahora el problema esta en la practica, una vez solucionado lo de la comunicación con el pc, empece a recibir los datos leídos del ADC que obtuvo del LM35 sengun su temperatura, pero resulta que me muestra siempre un valor de 15, ese valor es el que mas se mantiene, al ponerle una llama para incrementar la temperatura resulta que en vez de subir el valor lo que hace es bajar hasta 8 y 9, me resulta confuso ya que debería ser lo contrario, revise la hoja de datos y realice algunas modificaciones y sigue igual, busque en la red y encontré circuitos con la misma conexión así que descarto que este mal conectado. Les dejo el código y la simulación a ver si es que hay algo que no he tomado en cuenta y cualquier cosa me avisan muchas gracias de antemano:)
 

Adjuntos

  • 12F675 LM35 RS232.rar
    259.5 KB · Visitas: 124
Prueba nada mas asi Rey....
Código:
@ DEVICE PIC12F675
@ DEVICE INTRC_OSC_NOCLKOUT
@ DEVICE WDT_OFF       
@ DEVICE PWRT_OFF
@ DEVICE MCLR_OFF
@ DEVICE BOD_OFF
@ DEVICE PROTECT_OFF
@ DEVICE CPD_OFF 
Include "modedefs.bas"
DEFINE OSCCAL_1K 1
DEFINE OSC 4  


Define  ADC_BITS        10   	
Define  ADC_CLOCK       3  
Define  ADC_SAMPLEUS    50 
ADCON0 = %0
ANSEL = %1        
CMCON = 7            
SYMBOL TX = GPIO.5
SYMBOL LED = GPIO.2
TRISIO =%00000000     
GPIO  = %00000000     
TEMP VAR WORD
ATEMP Var Word


PAUSE 500
SEROUT TX,N2400,["BIENVENIDO",10,13]  
PAUSE 500
SEROUT TX,N2400,["TERMOMETRO DIGITAL",10,13]
PAUSE 500
SEROUT TX,N2400,["VERSION 1.0",10,13]
PAUSE 500

INICIO:

LED = 0
GOSUB ADC0
LED = 1 
PAUSE 100
GOTO INICIO


ADC0:                          
ADCIN 0, TEMP 
if TEMP<>Atemp then              		
 SEROUT TX,N2400,["TEMPERATURA ACTUAL: ", #TEMP,10,13]
 Atemp=Temp
endif
PAUSE 100
RETURN 
END

por ahi tengo un 675 y un lm35... mañana lo armo a ver que pasa, por curiosidad...:D
 
Dale lubeck muchas gracias, acabo de programar tu codigo y hacer pruebas los resultados son los siguientes:

temperaruta normal:

BIENVENIDO
TERMOMETRO DIGITAL
VERSION 1.0

TEMPERATURA ACTUAL: 2048
TEMPERATURA ACTUAL: 2112
TEMPERATURA ACTUAL: 1920
TEMPERATURA ACTUAL: 2048
TEMPERATURA ACTUAL: 2112
TEMPERATURA ACTUAL: 1920
TEMPERATURA ACTUAL: 2048
TEMPERATURA ACTUAL: 1920
TEMPERATURA ACTUAL: 2112
TEMPERATURA ACTUAL: 1920
TEMPERATURA ACTUAL: 2048
TEMPERATURA ACTUAL: 2112
TEMPERATURA ACTUAL: 2048
TEMPERATURA ACTUAL: 2176
TEMPERATURA ACTUAL: 1920
TEMPERATURA ACTUAL: 2048
TEMPERATURA ACTUAL: 2112

Temperatura modificada con una llama de encendedor:

BIENVENIDO
TERMOMETRO DIGITAL
VERSION 1.0

TEMPERATURA ACTUAL: 1024
TEMPERATURA ACTUAL: 1600
TEMPERATURA ACTUAL: 1152
TEMPERATURA ACTUAL: 768
TEMPERATURA ACTUAL: 896
TEMPERATURA ACTUAL: 1536
TEMPERATURA ACTUAL: 768
TEMPERATURA ACTUAL: 1088
TEMPERATURA ACTUAL: 1024
TEMPERATURA ACTUAL: 1152
TEMPERATURA ACTUAL: 1216
TEMPERATURA ACTUAL: 1280

Empiezo a pensar que esta defectuoso el LM35 :unsure:
bueno esperare haber si lo pruebas para confirmarlo, de momento, lo otro es que pretendia medirlo pero el multimetro se me a quedado en el maletín :rolleyes: y no lo tengo cerca, mañana lo busco para hacer mediciones, otra cosa hice pruebas colocando un potenciometro, con el primer código y me dio lecturas desde 1 hasta 480, con un POT de 50K. Osea si esta midiendo bien, ahora tengo la gran duda con el LM35:confused:,
 
Pues si con el pote y el codigo que te puse, el resultado es lineal de 0 hasta 65535 de 0 a 5v, entonces esta mal el LM35

mmm no recuerdo si el maximo son 1024 o 65535 pero alguno de los dos...
 
Una cosa que se me ocurre que vi es que el LM35 trabaja con 10mv entre °C, lo cual sugiere utilizar un Vref, para poder tener una mejor presicion, lo que he visto lo hacen con un regulador de voltaje o un divisor de tensión con dos resistencias de 10K, para lograr un voltaje de 2.5V aproximadamente, voy hacer una ultima prueba hoy y te aviso.
 
Ok si va, yo ya probé con lo del divisor y el Vref y mejoro bastante la parte de precisión antes cambiaba mas el valor ahora se mantiene, pero sigue cayendo el valor al subir la temperatura:confused:
 
mi lm35...

me marca 214mV y la temperatura en mi multimetro es 22°C le pongo el dedo y sube a 280mV el lm35, le pongo el cautin y se dispara a 300, 301.... 320 y va subiendo.... osea que es los mV/10=°C....

y si es bastante lineal
 
Si algo así imagine, ahora a esperar hasta mañana a ver, que es ,lo que le pasa a mi LM35 lo mas seguro es que este defectuoso, muchas gracias lubeck y si armas y pruebas el circuito me avisas un abrazo ya mañana te digo como me fue con las mediciones :apreton:
 
Ok...

una cosa yo estoy probando con un lm35 encapsulado TO-92, y visto de frente pongo en izq 5v, centro la salida Vout y derecha Gnd...

y si mañana lo armo para probarlo con el 675, abrazos y buenas noches...
 
KingValley....:D

ya lo arme.... y creo que algo si anda mal con el acople del Lm35 :cry:

quizas necesite un filtro...

mira la respuesta....
Dibujo.JPG es todo lo que marca ponga lo que le ponga, frio o caliente...

y mira el oscilos en el pin 7....

Dibujo1.JPG

sigo revizando a ver que pasa...

nada mas te lo comento para ver si se te ocurre algo...
 
Hola lubeck es un gusto saber que al parecer no perdi la inversion...:cool:...Dale muy bueno tus datos voy a echar andar las mediciones y a revisar el codigo y hojas de datos a ver que anda mal...Gracias por las pruebas (y) Apenas tenga algo te aviso...

Por cierto tengo el mismo LM35 y si revise muchas veces el pinaje para estar seguro que estaba bien conectado y ya tengo el multimetro...:D



:LOL:jajajajaja:LOL:.... No lo vas a creer al codigo solo le falta un 1 y listo funciona de maravilla...Increible la diferencia que puede hacer un simple 1 o 0 en el codigo, configura como entrada gpio.0 y listo prueba y veras como funciona;)
 
Última edición:
:LOL: apenas te iba a escribir que tenia un ruido infernal en el puerto gpio.0, pero lo puse como dijiste en entrada y como magia... se limpio... :D

definitivo era eso.... :D

ahora yo creo que para una mejor resolucion estaria bien con un operacional para que fuera mas exacto, y hacer las matematicas para el dato en °C...
 
Si aunque todo depende de la aplicación, yo diría que con un regulador de tensión para ajustar el Vref, es mas que suficiente ya que el mismo PIC tiene su propio amplificador, he visto que le colocan amplificadores adicionales para la señal de salida pero hasta el mismo datasheet lo que mas usa es un lm317 como ajuste de offset, la única que utiliza amplificador operacional es cuando vas a utilizar un ADC, de resto no haría falta, lo otro es que vallas a medir menos de medio grado, allí si diría que puede necesitar un amplificador, pero si vas a medir cambios de medio o un grado creo que lo mas que haria falta es un regulador para el ajuste del Vref.
 
la única que utiliza amplificador operacional es cuando vas a utilizar un ADC,

por eso te lo menciono estamos utilizando un ADC con el 12f675... mmm.. no se como explicarlo pero el rango del ADC es de 0 a 5V... y con el LM35 tenemos un rango de digamos 0 a 1.5V ya exagerado estamos ocupando solo el 30% del rango... si esos 1.5 lo escalamos a lo 5v (100%) queda mas fino el resultado... pero como tu dices si no es necesario pues pa'que:D
 
No se si te mencione pero coloque un divisor de tension con dos resistencias de 10K para el voltaje de referencia para el ADC, ya con eso tendrías el 100% como indicas ya que el adc no tomaria de 0V a 5V si no de 0V a 2.5V, aunque ahora que mensionas lo del voltaje se puede hacer una prueba llevando Vref a 1,5V y ver que pasa como el ADC, aunque lo que mas he visto es que lo llevan a 2.5V no se porque seria esto, si como dices tu que es totalmente cierto el rango de voltaje de salida del LM35 es de 0V a 1.5V:confused:

Nota: adcon0 quedo así: ADCON0 = %01000000
para que tome el voltaje de referencia a través del pin 6.

PD: aquí hay uno con amplificador para adaptar la señal como indicas lubeck.

https://www.forosdeelectronica.com/f23/dudas-operacinales-67698/#post593366
 
Última edición:
Hola yo de nuevo por aca, estoy ahora probando un poco lo que es registro TMR0 y el Timer0, al principio tenia dudas con respecto a quien era quien, luego leyendo la hoja de datos en este caso uso el 16F877, encontré que el TMR0 es un registro que contiene los bit de Timer0, por lo tanto ya a partir de allí empece a investigar como usarlo y como calcular el tiempo, ahora debido a que se utiliza PBP y si fuera ASM seria mas o menos igual, al realizar una interrupcion por TMR0 por desbordamiento, yo realizo una operación para incrementar o decrementar un registro de propósito general, en este punto se debe tomar en consideración cuanto es el tiempo que se utilizo al realizar el incremento, ya que de lo contrario nos daría un desfase de tiempo. Luego de este pequeño analisis segun yo, suponiendo que saque mis cuentas bien y estoy en lo correcto pongamos que se cargo el prescaller con un valor de tal manera que me genere una interrupción en 1 mili segundo exacto y yo cargo un registro y al llegar a 1000 milisegundos tendría 1 segundo y a partir de allí incrementaría otro registro de propósito general para poder controlar un sistema de tiempo lo mas real posible, ahora por cada vez que exista un desbordamiento yo realizo de 2 a 3 o 4 consultas para cada uno de los registros y aparte de eso realizo un incremento constante de los registro según sea el caso si el primero llamado milisegundos = 1000 entonces reseteo el registro milisegundos, e incremento el de segundo 1, y a su vez decremento el tiempo que me llevo realizar toda la operación, incluyendo en tiempo del decremento claro esta, y por cada desbordamiento tengo que hacer lo mismo ya que al realizar cada consulta estoy usando tiempo. Ahora como casi me vuelvo loco :eek: , con todo esto, eso es solo con la rutina de tiempo, falta el programa principal que también afecta el tiempo, yo optaría por usar una subrutina para ciertas sentencias y como en un goto seria 2 ciclos de maquina, mas lo que restaría por la operación anterior, no se si todo es cierto o no, pero si es cierto tengo una pregunta, yo recuerdo que en algun momento en la carrera de electrónica, en la materia de micros1, nos pusieron en un examen un código en ASM, para un pic, que trabajaba a xxmhz, y teníamos que calcular el tiempo en el el micro tardaba en ejecutar todo el programa era algo largo el proceso y algo tedioso pero interesante, para este caso que explico tendría que hacer lo mismo para poder tener una buena precisión en el tiempo? Espero si alguien puede ayudarme con esas dudas se lo agradecería mucho :D
 
Bueno aqui dejo un codigo base para un tiempo de 999.96 milisegundos, practicamente 1 segundo, con un error de 4us, creo puede mejorarse :D, en fin no es muy complicado pero si es necesario conocer mas a fondo los ciclos de maquina para mayor precisión, aparte de tener en cuenta el oscilador a utilizar y que rango del divisor prescaller usar, en mi caso, no necesito tanta precisión pero quise llevarlo un poco mas allá, y logre hasta 999.96ms, para llegar aquí primero coloque al máximo el prescaller osea 256, osea cada 256 ciclos el cuenta 1, como cada ciclo de maquina es de 4 pulsos de reloj, en la formula que encontré del TMR0, es por eso la multiplicación por 4 luego de la división de 1/F, lo que da 1us por cada ciclo de maquina para los microcontroladores pic, eso utilizando un oscilador de 4MHZ, si es de 20MHZ da 0.2us, para poder lograr mas o menos 1 segundo con un margen de error mínimo con 20MHZ, lo que hice fue escoger un valor redondo en mi caso 12800us, utilizando un programa que encontré y anexo,
esos 12800us me dan con un valor de 6 cargado en el registro TMR0, lo que quiere decir que a partir de alli es que empieza a contar,
o lo que es lo mismo le resto a 256 - 6, entonces ahora no desborda al contar de 00 a 256, si no de 06 a 256,
si sacamos cuenta, para ciclos
con duración de 0.2us x 250 = 50us x 256 = 12800us = 12.8ms,
ahora eso no es ni la mitad de un segundo, para llegar a 1 segundo, multiplique cuantas veces fue necesario para llegar lo mas cerca a 1 segundo,
en mi caso elegí 78 que da 12.8ms x 78 = 998.4ms,
elegí ese porque era el mas redondo de los que calcule, ahora tengo una diferencia de 1,6ms, para compensarlo coloque 20us de pausa por cada interrupción
como son 78 entonces 20us x 78 = 1560us = 1.56ms
Y en total tenemos 998.4ms + 1.56 = 999.96ms por cada 78 interrupciones.
Ahora esto es relativo, si sabemos que cada ciclo es de 0.2us, si después de la interrupción, hacemos un procedimiento ya sea de suma o condicional, eso consume ciclos de maquina lo cual debe restarse del tiempo calculado,
digamos que un IF THEN, consume 2 ciclos de maquina,
entonces tendríamos que multiplicar 0.2us x 2 x 78 y nos daría cuanto es el tiempo que tendríamos de diferencia para 1 segundo con esa instrucción y así para cada instrucción que se vaya a realizar en la subrutina de interrupción.

Bueno hasta aquí la pequeña explicación dejo el programa, el código y la simulación para que la prueben, el código esta comentado en ingles para los registros de interrupción y option lo coloque así por que se entiende mejor que al traducirlo.

El programa lo que hace es togglear un led cada segundo bueno cada 999.96ms aproximadamente...Cualquier cosa que me este equivocando me avisan...(y)

PD: El pulsador no tiene ninguna función de momento era para las practicas, en el proteus tienen una opción que esta en la barra de herramientas debug que se llama "Excute For Specified Time", sirve para ejecutar la simulación en un tiempo especificado es milisegundos, para menor tiempo pueden poner 0.500 y es medio segundo.
 

Adjuntos

  • PRACTICA TMR0 16F877.rar
    184.5 KB · Visitas: 114
Última edición:
Atrás
Arriba