sábado, 22 de julio de 2017

OSCILOSCOPIO- Arduino - STM32F103C8T6



OSCILOSCOPIO
Arduino

STM32F103C8T6
640000 muestras segundo
Fast A/D


En mi anterior montaje había realizado un osciloscopio con un arduino. Había conseguido una tasa máxima de muestreo de 250000 muestras por segundo. El programa estaba realizado utilizando la librería SDL en la parte del PC.
Como tenía un arduino basado en un STM32F103C8T6 , un  procesador  bastante mas potente que el ATmega 328 , investigue si podía conseguir una tasa de muestreo algo mas elevada.
Según la tabla de características del  STM32F103xx  performance line devices: 1 μs at 56 MHz (1.17 μs at 72 MHz).
Se raro que indique mas rapidez de conversión a 56 MHz que a 72 MHz , pero el caso es que en teoría podría llegar a una tasa de muestreo de 854000 muestras por segundo.
Mi idea era mantener el interface SDL del anterior montaje y cambiar el programa arduino de obtención de datos en la placa STM32F103, ajustándolo al nuevo procesador.
Lo primero que intente con éxito era cambiar la orden del conversor A/D  y utilice la orden: adc_read(ADC2, 0) , donde el 0 es el pin A0 que corresponde al PA0 en el programa.
El programa funcionaba, pero no se conseguía un aumento significativo en la tasa de conversión.
Mirando por internet encontré una fórmula para cambiar el reloj del conversor A/D con la orden: adc_set_prescaler(ADC_PRE_PCLK2_DIV_4) .
Puede tener tres opciones:
  ADC_PRE_PCLK2_DIV_2
  ADC_PRE_PCLK2_DIV_4
  ADC_PRE_PCLK2_DIV_6
  ADC_PRE_PCLK2_DIV_8

Con este cambio en la frecuencia de reloj, cambiamos la tasa de muestreo.

Clock configuration register (RCC_CFGR)
Address offset: 0x04
Reset value: 0x0000 0000
Access: 0 ≤ wait state ≤ 2, word, half-word and byte access
1 or 2 wait states inserted only if the access occurs during clock source switch.

Bits 15:14 ADCPRE: ADC prescaler
Set and cleared by software to select the frequency of the clock to the ADCs.
00: PCLK2 divided by 2
01: PCLK2 divided by 4
10: PCLK2 divided by 6
11: PCLK2 divided by 8


Pero aún así no llegábamos a la tasa de muestreo que prometían las especificaciones del procesador.
Buscando por internet encontré en un foro http://www.stm32duino.com/viewtopic.php?t=847  la forma de aumentar la tasa de muestreo.
La forma era con el comando: adc_set_sample_rate(ADC2, ADC_SMPR_13_5);
Efectivamente, aumento la tasa de muestreo a mas de 600000 muestras por segundo.
Las opciones posibles son:
    ADC_SMPR_1_5,               /**< 1.5 ADC cycles */
    ADC_SMPR_7_5,               /**< 7.5 ADC cycles */
    ADC_SMPR_13_5,              /**< 13.5 ADC cycles */
    ADC_SMPR_28_5,              /**< 28.5 ADC cycles */
    ADC_SMPR_41_5,              /**< 41.5 ADC cycles */
    ADC_SMPR_55_5,              /**< 55.5 ADC cycles */
    ADC_SMPR_71_5,              /**< 71.5 ADC cycles */
    ADC_SMPR_239_5,             /**< 239.5 ADC cycles */
Aunque no entiendo muy bien lo que realmente hace, el manual del registro dice:
ADC sample time register 2 (ADC_SMPR2)
Address offset: 0x10
Reset value: 0x0000 0000

Bits 29:0 SMPx[2:0]: Channel x Sample time selection
These bits are written by software to select the sample time individually for each channel.
During sample cycles channel selection bits must remain unchanged.

De las prueba realizadas la mejor combinación para dar una tasa de muestreo de 640000 muestras/segundo  es :
adc_set_prescaler(ADC_PRE_PCLK2_DIV_2) ;
adc_set_sample_rate(ADC2, ADC_SMPR_7_5);


Visualización de una frecuencia de 16000Hz . Muestreo de 640000 muestras/seg.

Para poder visualizar y medir mejor las ondas, he incorporado botones de zoom y de desplazamiento de onda.

Visualización de la onda 16KHz con zoom x4 modo puntos.

 
Visualización de la onda 16KHz con zoom x4 modo lineas.

Podemos observar 40 muestreos en un ciclo de onda de 16KHz.
Si calculamos 16000x40=640000 muestras/segundo.



PROGRAMA

Nota:
Debemos tener en cuenta que la máxima tensión de entrada es de 3.3V , que también es la tensión de alimentación del procesador.
La impedancia de entrada es mucho mas baja que en un arduino convencional,  lo que debemos tener en cuenta.
La propia sonda del osciloscopio me producía ruido en el propio chip.



Saludos
Juan Galaz



Bibliografía:
oscisdl.html
http://www.stm32duino.com/viewtopic.php?t=847
https://github.com/leaflabs/leaflabs-docs/blob/master/source/libmaple/overview.rst
https://hackaday.io/project/425-arduino-oscilloscope-688000-samplessec


www.000webhost.com

sábado, 8 de julio de 2017

OSCILOSCOPIO con el arduino Arduino



OSCILOSCOPIO
Arduino



Hace tiempo hice un osciloscopio con arduino en el entorno  de programación Gambas. El entorno gambas es una especie de VB que solo funciona en Linux. El que solo funcione en Linux tiene el inconveniente de eliminar bastantes usuarios que solo usan Windows.
Mi idea era era volver hacer el osciloscopio mejorándolo y que además funcionase  en Windows.
Había dos opciones hacerlo con las librerías SDL o con las librerías wxWidgets. Está claro que hubiese quedado mucho mejor el aspecto con las librerías wxWidgets, pero me decidí por las SDL por un motivo un tanto personal que no viene al caso. Igual en un futuro lo realice en wxWidgets , pero eso es otro proyecto.
Lo que me satisface más, es el poder compilar para las dos plataformas, Linux o Windows, con solo cambiar la directiva YesWindows 0 por #define YesWindows 1 en el fichero define.h.

En lado del arduino la entrada la toma del pin A0 con valores de 0 a 5V.
El arduino lee continuamente el puerto serie esperando ordenes.
En el caso de recibir la cadena "VOL="  , el devuelve una cabecera de 10 bytes "VOL     " + los retornos de carro , 10 valores (0-255) digitalizados de la entrada A0, y 10 bytes con la cadena "FIN     " + los retornos de carro. Un total de 30 bytes.
En caso de recibir "GETUP=" , el devuelve una cabecera de 10 bytes "DAT     " + los retornos de carro , 800 valores (0-255) digitalizados de la entrada A0, y 10 bytes con la cadena "FIN     " + los retornos de carro. Un total de 830 bytes.
En caso de recibir "DIV16" cambia el divisor del convertidor A/D del arduino a 62500 muestras por segundo.

En el lado del PC nos encontramos un entorno en el que podemos representar y controlar los datos que nos envía  el arduino.
Podemos estar en el modo Vol  ( Voltímetro ) , captura continuamente datos digitalizados del pin A0 representándolos en una gráfica continua. Se puede cambiar la velocidad de captura de datos.
El modo de osciloscopio muestra continuamente datos mandados por el arduino, 800 datos digitalizados a una velocidad que podemos modificar a nuestro gusto.

Al iniciar el programa se busca la conexión  del arduino con el programa del osciloscopio en todos los puertos serie que existan en el PC.
Este es el motivo por el cual tarda unos 6 segundos en arrancar

Para calcular la frecuencia de la onda debemos dividir las muestras por segundo entre las muestras de cada onda.
En la imagen siguiente la onda mide alrededor de 200 muestras.
Si estamos en el modo de 125000 muestras por segundo, la frecuencia será 125000/200=625Hz
Este cálculo no es totalmente exacto, pero la mayoría de las veces funciona bien.
En un principio lo incluí en el código, pero después de muchos ensayos lo descarté por no ser totalmente exacto.


Señal de 625Hz


Montaje del circuito.

En las siguientes imágenes se puede comparar entre las de un osciloscopio normal y mi montaje.



Señal de 5000Hz



Señal de 625 Hz

Para medir señales continuas o de niveles positivos se conecta la señal directamente a A0.
Pero si queremos medir corrientes alternas, debemos realizar un adaptador para elevar la señal a mitad de la máxima señal de entrada, 2.5V.
Como no quiero complicar el montaje, utilizo un par de resistencias y un condensador.

Adaptador de AC.

Para los que no disponen de un osciloscopio, este montaje puede ser interesante además de barato.

PROGRAMAS
Librerías necesarias SDL


Nota:
He tenido serios problemas con los diferentes arduinos. Cuando funcionaba bien el programa en una placa arduino clásica, luego al probar el programa en un arduino nano, dejaba de funcionar.  A velocidades de 115200bps no todo se comporta como debería.
He tenido que colocar retardos para que sea lo mas compatible posible.
La compilación en arduino se hizo en la versión 1.0.5 .
También he visto que la velocidad del programa es más rápida en la versión Linux.


Saludos
Juan Galaz



Bibliografía:
ardu_os.html
http://real2electronics.blogspot.com/2011/09/arduino-adc-muestreo-alta-velocidad.html