sábado, 29 de junio de 2019

Arduino - TM1638 - Medidor de inductancia

Página principal

Arduino
TM1638
Medidor de inductancia


En este artículo enseñaré como medir inductancias.
Cuando sobre un circuito LC se aplica durante unos instantes una corriente, el circuito entra en oscilación a una frecuencia determinada por L y C.
Si fueran inductores ideales, sin resistencia, y condensadores ideales, sin perdidas en el dieléctrico, el circuito entraría en oscilación constante.
Pero esto no es así, la energía que se traslada del inductor al condensador y del condensador al inductor se va perdiendo.
Esto produce que la onda se va atenuando hasta desaparecer.

Atenuación del circuito oscilante.


Esta onda tiene un periodo que se puede medir.

La frecuencia de esta onda se calcula con la siguiente formula.

Para medir la frecuencia de un circuito LC montamos un oscilador mediante un  MC14049 (puerta inversora CMOS).

Esquema del circuito oscilante.

Con un C conocido (150nF) y un medidor de frecuencia, podemos calcular la inductancia L .
Como el montaje debe ser sencillo, utilizamos a modo de frecuencímetro un arduino.

El arduino no está preparado para medir frecuencia , las puertas de entrada están sincronizadas con el reloj interno. Además de tener en algún momento interrupciones que modifican la cuenta de la frecuencia.
El medidor de frecuencia no es demasiado exacto, pero sirve perfectamente para medir inductancias entre 15uH y 100uH. Para inductancias mayores se produce un error alto 12% .

Diagrama del montaje.


Circuito montado.

La medida de la inductancia se manda por el terminal serie.
Como tenía el módulo TM1638  lo he utilizado para mostrar la inductancia sin necesidad de un PC.

Espero que os haya gustado este montaje, y que os de ideas para otros montajes.
En posteriores versiones intentaré ajustar mas la medición de frecuencia.


PROGRAMA

VIDEO


Saludos.
Juan Galaz


miércoles, 19 de junio de 2019

DS1077 Divisor de frecuencia programable. Generador de frecuencia. Arduino

Página principal

DS1077

Divisor de frecuencia programable.
Generador de frecuencia

Arduino


En este artículo enseñaré como generar frecuencias diferentes con el chip DS1077.
El chip DS1077 es un doble divisor de frecuencia programable.
El oscilador de frecuencia se encuentra internamente en el chip, no tiene cristal, por lo cual la frecuencia no suele ser demasiado exacta.
Dependiendo del modelo, el oscilador interno puede estar entre 66Mhz y 133Mhz ( DS1077x-66 para 66Mhz).
El modelo que he utilizado para el montaje es el de 66Mhz.




En el primer divisor programable, salida OUT0, solo se programa el divisor P0 para que divida por 1,2,4,8.
 PRESCALER P0 (0M1-0M0)
0 MCLK /1   66,6 MHz
1 MCLK /2   33,3 MHz
2 MCLK /4   15,65 MHz
3 MCLK /8   8,32 MHz
Además se puede habilitar/deshabilitar la salida OUT0 internamente o externamente con el pin CTRL0.
En nuestro montaje colocaremos CTRL0 y CTRL1 a GND para que esté habilitado.

El segundo divisor programable, salida OUT1, también tiene el prescaler programable P1, para que divida por 1,2,4,8.
 PRESCALER P1 (1M1-1M0)
0 MCLK /1   66,6 MHz
1 MCLK /2   33,3 MHz
2 MCLK /4   15,65 MHz
3 MCLK /8   8,32 MHz

La salida del prescaler P1 se conecta a un segundo divisor programable N, que se puede programar para que divida entre 2 y 1025.
DIV
DIV-decimal
DIVISOR
0 000 000 000
0 000 000 001
0 000 000 010
0 000 000 011
1 111 111 111
0
1
2
3
1023
/2
/3
/4
/5
/1025


Por ejemplo para conseguir una frecuencia de 100Khz deberíamos programar los dos divisores programable de la siguiente forma:
-El prescaler P1 lo dejaríamos dividiendo por 1. Con lo que la frecuencia quedaría a 66666Khz.
-Para conseguir 100KHz deberemos dividir 66666Khz/100 =666.
-Al ser el divisor 666, el valor que debemos colocar en DIV será 666-2=664.
-664 en binario será  b0000 0010 1001 1000  , pero hay que desplazarlo 6 bit a la izquierda, b1010 0110 0000 0000 , 42496 en decimal.

Como segundo ejemplo, para conseguir 15Khz realizaremos los siguientes cálculos.
-El prescaler P1 lo dejaríamos dividiendo por 8. Con lo que la frecuencia quedaría a 8333Khz.
- 8333Khz/15=555, valor en DIV  555-2=553
- 553 -> b00 0010 0010 1001  , desplazado 6 bit a la izquierda, b1000 1010 0100 0000 -> 35392 en decimal.

En los cálculos he ignorado los decimales a modo de ejemplo.

El chip DS1077  se programa mediante 2-wire serial interface , que se conectan a los pin del arduino A4 y A5.
DS1077_ADDRESS 0b1011000
Access DIV [01]
If R/ W is 0, this command writes to the DIV register. After issuing this command, the next data byte value is to be written into the DIV register.
If R/ W is 1, the next data byte read is the value stored in the DIV register.
Access MUX [02]
If R/ W is 0, this command writes to the MUX register. After issuing this command, the next data byte value is to be written into the MUX register.
If R/ W is 1, the next data byte read is the value stored in the MUX register.
Access BUS [0D]
If R/ W is 0, this command writes to the BUS register. After issuing this command, the next data byte value is to be written into the BUS register.
If R/ W is 1, the next data byte read is the value stored in the BUS register.
Write E2 [3F]
If WC = 0 the EEPROM is automatically written to at the end of each command. This is a DEFAULT condition. In this case the command WRITE E2 is not needed.




Para todos los cálculos he supuesto que la frecuencia del MCLK es de 66.666.666 Hz para el chip empleado.
Pero después de mucha medidas, debido a que me daba error en las frecuencias, he descubierto que la frecuencia real es de aproximadamente 65800 Khz, lo que hay que tener en cuenta para los cálculos.
La tolerancia teórica es de 0,5% , pero como vemos en nuestro caso es de 1,29% .
Por este motivo, si se quiere tener una frecuencia precisa debemos ajustar la frecuencia real de MCLK con la orden:
    FREB 65800

En este chip también se puede programar en su EEPROM el valor inicial de los registros, y de esta forma, la frecuencia inicial que saldrá por OUT0 y OUT ,  sin haber programado el chip.

El programa realizado para el arduino escucha las ordenes que recibe por el puerto serie, y las ejecuta.
Comandos reconocidos
MDIV    [0-1]        Activar prescaler [0=enable, 1=disable]
DIVX    [0-1023]  Divider         dividir[2-1025]
        00000000 00000000    /2   
        00000000 00000001    /3   
        00000000 00000010    /4   
        00000000 00000011    /5   

MX0M    [0-3]    Prescaler 0        div[1,2,4,8]
MX1M    [0-3]    Prescaler 1        div[1,2,4,8]

FREB    [Frecuencia KHz]     Default=66666
FREC    [Frecuencia]
LIST    Lista todos los estados

RDIV    [0-65536]
RMUX
    [0-65536]
RBUS
    [0-65536]
RWRI
    [0-65536]
Existen dos versiones de programa arduino, versión 0 y versión 1.
La versión 0 solo admite los comandos FREB y FREC .
La versión 1 admite todos los comandos.


Con cualquier programa de terminal serie se pueden mandar las ordenes.
Ejemplo:
    FREC 35000
Nos generaría una frecuencia de 35000Hz en OUT1.

Para hacer mas fácil la programación del chip he realizado dos programas, uno en python y otro en Gambas (VB para Linux).
Su transformación para que funcionase en Windows en el caso de Python es fácil, solo cambiar la lista de dispositivos serie.


Programa en python.


Programa en Gambas (VB para Linux)


Visualización de la onda en mi osciloscopio digital DSO-6022BL.

Espero que os haya gustado este montaje, y que os de ideas para otros montajes.

PROGRAMA

VIDEO


Saludos.
Juan Galaz


Bibliografía:
http://wardy2.rssing.com/chan-9972730/all_p2.html
http://jondontdoit.blogspot.com/2012/08/using-ds1077-programmable-oscillator.html
http://ferretrobotics.blogspot.com/2013/08/ds1077-programmable-oscillator.html
https://www.sparkfun.com/products/retired/9089

martes, 11 de junio de 2019

Gráficas de datos metereológicos. Python. Generar página web.

Página principal

Gráficas de datos metereológicos.
Python.
Generar página web.


Continuamos con la serie de artículos sobre servidor web.
En el último artículo había creado un visualizador de temperatura, humedad y presión. Además de visualizar los datos, creaba un registro diario de los datos.
El archivo de los datos está bien, pero su visualización e interpretación es poco útil si no se ven los datos gráficamente.
En este artículo se representan los datos en dos gráficas, una de temperaturas por horas, y en la otra la representación de humedad y temperatura en función de la hora.
Aunque no soy muy partidario del lenguaje python, he de reconocer que se hace muy fácil trabajar con el debido a la gran cantidad de librerías que existen para casi cualquier cosa.
Para este programa hacemos uso de la librería matplotlib. Esta librería se emplea para hacer todo tipo de gráficas. La librería está muy extendida, además de disponer de mucha documentación y una excelente página web.
Con esta librería creamos las gráficas anteriormente mencionadas, para luego exportarlas como imágenes con formato  *.png. Las imágenes creadas será luego las que se visualizaran en la página web.

Lo primero que debemos hacer para crear una gráfica es tener los datos, estos datos los obtenemos del fichero diario con el nombre:
"Temp"+ time.strftime("%y_%m_%d")+".cvs"
Creamos una matriz donde se almacenan todos los datos de temperatura, humedad y presión, donde se ordenan por horas y minutos.
Debo de anotar que crear matrices en python es un poco peculiar, no existe la creación de matrices como en otros lenguajes, debemos crearlas añadiendo datos, es de lo mas frustrante, aunque tiene otras ventajas este lenguaje.

Crear una gráfica de cada minuto de las 24 horas del día es innecesario, lo he reducido a 10 datos cada hora, o lo que es lo mismo cada 6 minutos.
Creo otras listas con los datos que realmente voy a utilizar para la gráfica. En total serán 10 muestras por hora, y como son 24 horas, el total de datos representados serán 240.
Las listas de datos son la siguientes:
    listaTemp , listaHume, listaPres
Estas son las lista de datos que voy a proporcionar a la librería  matplotlib para que cree las gráficas.


Código de creación de la gráfica de temperatura.
fig = plt.figure()                                                              
ax = fig.add_subplot(1,1,1)
major_ticks = np.arange(0, 240, 30)                                             
ax.set_xticks(major_ticks)
ax.grid(which='major', alpha=1)

plt.xlabel("Temperatura DIA "+ time.strftime("%d_%m_20%y"))
plt.plot(listaTemp,color='red')
plt.xlim(0,240)
plt.ion()

my_dpi=75
plt.savefig("gra2.png",dpi=my_dpi)


Código de creación de la doble gráfica de humedad y presión.
fig, (ax1, ax2) = plt.subplots(2, sharex=True,)

plt.xlim(0,240)
ax1.plot(listaHume,color='blue')
ax1.set(ylabel='Humedad %')

plt.xlim(0,240)
ax2.plot(listaPres,color='green')
plt.setp(ax2.get_xticklabels(), fontsize=9)

major_ticks = np.arange(0, 240, 30)                                             
ax2.set_xticks(major_ticks)

ax2.set(ylabel='Bares')
plt.xlabel("HORA "+time.strftime("%H:%M"))

my_dpi=75
plt.savefig("gra1.png",dpi=my_dpi)

En las siguientes imágenes se pueden ver los gráficos creados.


  Gráficas pertenecientes a Palencia, ESPAÑA

Se puede estudiar las gráficas y observar el cambio de presión preludio de lluvia.
Después de la lluvia observamos también como aumenta la humedad en el ambiente.
Estas dos imágenes son las que se incorporan en la página web para hacer mucho mas intuitiva el estudio de los datos.

Para ejecutar el programa en python he creado un programa en bash llamado gratem.sh que se ejecuta cuando se inicia el ordenador.
gratem.sh
#!/bin/bash
echo "GENERANDO GRAFICOS"
cd $HOME/www/webcam
$HOME/www/webcam/gratem.py
Ya tenemos el script creado, pero nos falta que el script se ejecute cada 10 minutos.
Para esta tarea utilizaremos cron.  El comando cron es un administrador regular de procesos en segundo plano que viene de serie en linux.
Para añadir el comando que se debe ejecutar en segundo plano, utilizaremos el comando crontab -e  .
Editaremos de la siguiente forma:

    */10 * * * * /home/seta/www/webcam/gratem.sh > $HOME/tmp/cron.log 2>&1

De esta forma el script  de generación de gráficas se ejecutará cada 10 minutos.

Podéis comprobar el resultado en mi página:
http://seta43.duckdns.org/seta/webcam/gradia.html
http://seta43.ddns.net/seta/webcam/gradia.html
Espero que os guste este artículo, y que os sirva para vuestros proyectos.

PROGRAMAS

Saludos
Juan Galaz

Bibliografía:
https://matplotlib.org/index.html
https://claudiovz.github.io/scipy-lecture-notes-ES/intro/matplotlib/matplotlib.html
https://github.com/japp/Computacion-Cientifica/blob/master/graficos.rst



miércoles, 5 de junio de 2019

Sensores-Tratamiento de datos metereológicos con Python - Generar página web con temperaturas

Página principal

Sensores

Tratamiento de datos metereológicos
con
Python
Generar página web de temperaturas


Este artículo es una continuación de una serie de artículos sento.html , oracam.html, serora.html .
El propósito de este artículo es capturar los datos que manda un módulo ( en este caso un arduino con sensores) a través del puerto serie ( /dev/ttyUSB0', '/dev/ttyUSB1','/dev/ttyACM0','/dev/ttyACM1'....) y procesarlos para guardarlos en un fichero ( ejemplo: Temp2019_06_04.csv ).
Además de todo lo anterior, creará una página web donde se visualizarán los datos a través de un servidor web.
No soy muy partidario de Python, pero al estar muy implantado en todas la plataformas del tipo Raspberry o Orange-PI,  que es donde se va montar el servidor, la programación se va a realizar en este lenguaje. Deberéis perdonar lo mal que sé programar en Python, soy novato en este lenguaje de programación, normalmente programo en C/C++ o Básic.

Lo primero es saber el formato que tienen los datos que transmite el modulo de sensores (arduino) a través del puerto serie.
Formato de datos
INICIO
Temperatura,14.0
Humedad,32
#presion,923
#Temperatura,26.1
FINAL
Como podéis observar el formato es bastante simple:
Dos cadenas INICIO y FINAL, y en medio datos.
Cada línea de datos está compuesto del tipo de dato y el valor, separados por una coma.

Lo primero que hace el programa es buscar el módulo en todos los puertos serie posibles.
Al escanear los puertos, si existe el módulo, responderá el módulo con la palabra SENSORTOTAL empezándose a ejecutarse la rutina principal del programa.

En la rutina principal del programa, se lee continuamente el puerto serie hasta que encuentra datos a procesar.
Cuando encuentra datos, los almacena en las variables  dTemperatura, dHumedad, dPresion.
La visualización en tiempo real se realiza en consola.


Cada minuto se van almacenando las variables en un fichero con el formato TempAÑO_MES_DIA.csv  .
Ejemplo : Temp2019_06_04.csv
Esto se realiza con los comandos en python:
nombreFichero="Temp20"+time.strftime("%y_%m_%d")+".csv"
f = open(nombreFichero,'a')
f.write(time.strftime("%H,%M"))
f.write(',')
f.write(dTemperatura+','+dHumedad+','+dPresion+','+'\n')
f.close()

Como podéis observar cada día se crea automáticamente un fichero de datos.
Formato del fichero de datos metereológicos
00,00,21.6,25,924,
00,01,21.6,25,924,
00,02,21.6,25,924,
00,03,21.6,25,924,
00,04,21.5,25,924,
Lo bueno de este formato es que se puede importar con una hoja de cálculo para su tratamiento.

El programa, cada 41 segundos o cada vez que recibe datos del módulo de sensores, actualiza el fichero  index.html que es el que se representa en la página web.
El código python que se utiliza para crear la página web es el siguiente:
            print "Crear pagina"
            fw = open('index.html','w')

            mensajeWeb = """
<html>
<head>
    <meta http-equiv="refresh" content="115">
    <title>PALENCIA</title>
</head>
<body bgcolor="#ffff99">
<h2>Palencia, Spain
<hr size="2" width="100%">
<img  alt="" src="web.jpg" height="480" width="640"><br>
<hr size="2" width="100%">
"""
            mensajeWeb = mensajeWeb + time.strftime("%d/%m/%y") +"  "+ time.strftime("%H:%M:%S")
            mensajeWeb = mensajeWeb + """<br>"""
            mensajeWeb = mensajeWeb + mensaje
            mensajeWeb = mensajeWeb + """
<h2><a href="gradia.html">GRAFICOS</a><br>
<img  alt="" src="mapa.png" >
</h2>           
</body>
</html>"""

            fw.write(mensajeWeb)
            fw.close()
Como había veces que los navegadores utilizaban la cache, y para que se actualizase cada 2 minutos, añadí en la cabecera del fichero html :  <meta http-equiv="refresh" content="115">
Con lo que obliga al navegador a actualizar automáticamente la página web.
El resultado es el siguiente:


Podéis comprobar el resultado en mi página:
http://seta43.duckdns.org/seta/webcam/index.html
http://seta43.ddns.net/seta/webcam/index.html
El resultado no lo he hecho muy vistoso a propósito, para hacer mas legible el código, el que quiera lo puede mejorar retocando el código html.

Para ejecutar el programa en python he creado un programa en bash llamado app_python.sh que se ejecuta cuando se inicia el ordenador.
app_python.sh
#!/bin/bash
cd /home/seta/www/webcam
xterm -e "python camtem4.py"
He de reconocer que en mi placa OrangePI no consigo que se inicie automáticamente, aunque en el ordenador PC se inicie perfectamente, y mira que lo he revisado, pero nada, lo debo iniciar yo, por lo cual si se va la luz en el servidor, debo lanzarlo yo remotamente.

PROGRAMA


Saludos.
Juan Galaz


Bibliografía:
https://pyserial.readthedocs.io/en/latest/
sento.html
predi.html
raspb.html
arterec.html
tm16tem.html