El zener de 5 V funciona como protección, pues un voltaje mayor de 5V quemaría el arduino aunque podría afectar negativamente al circuito que vamos a medir, para medir voltajes mayores se puede usar un divisor resistivo y con menores de 5V el zener es prescindible. La punta de prueba negra va a masa y la morada al + del circuito a visualizar.
Uno de los potenciómetros es para controlar el contraste de la pantalla y el otro controla el tiempo que dura el muestreo de datos, la frecuencia muestrada es solo una estimación parcial basada en el numero de picos representados en el tiempo muestreado, por lo que sólo va a ser precisa cuando se vean muchos picos, el motivo de esta inexactitud es para mentener cierta agilidad en la visualización de nuestro mini osciloscopio..
He incluido una variación del sketch donde se modifica el prescaler del arduino y se consigue un muestreo unas 8 veces más rápido, pero su funcionamiento es algo menos fluido . El valor divisor mínimo que admite sin que la visualización resulte muy afectada es 16, con las pruebas configurado a 32 el funcionamiento ha sido impecable y se ganaba una velocidad de aproximadamente el triple.
A partir de 5 mseg, el comnportamiento del programa cambia, se convierte en un pequeño monitor de la tensión adecuado a otros usos.
Para que funcionen los sketch hay que tener instalada la librería U8glib.
_______________________________________________________________________________________________________
Visualización de una salida PWM de otro arduino y de su filtrado con condensador de 100uF.
Hemos configurado un segundo arduino producir
una salida de tensión PWM , pudiendola variar mediante un
potenciometro y poder visualizarla. Después la hemos filtrado y vemos
como se muestra.
PWM 0.3 V
filtrada con condensador en paralelo:
PWM 3V
filtrada (100uF):
PWM 5V:
Video:
Onda senoidal 50Hz (red eléctrica, a través de unas espiras próximas a un transformador 12V.)
Onda cuadrada IC 555.
Sketch con el prescaler modificado. Descargar.
#include "U8glib.h"
U8GLIB_ST7920_128X64_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); //For ST7920_128X64 paralelo
unsigned long sensor;
int muestreo;
int x;
int y[130];
boolean monitor;
int y2;
unsigned long ycal;
// unsigned long tpo;
byte punto;
byte y3;
float mx;
byte mc;
byte fc;
void setup(void) {
}
void loop(void) {
u8g.firstPage();
// Captación de muestreo
muestreo =analogRead(A1);
if (muestreo < 512) { // Osciloscopio
monitor=0;
if ( muestreo <256 a="" br="" mecha="" nbsp="" osciloscopio="" toda="">
switch(byte(4+2*float(muestreo/256)))
{
case 0: // <4 br="" malfuncionamiento=""> bitWrite(ADCSRA,ADPS2,0); bitWrite(ADCSRA,ADPS1,0); bitWrite(ADCSRA,ADPS0,0);
break;
case 1:
bitWrite(ADCSRA,ADPS2,0); bitWrite(ADCSRA,ADPS1,1); bitWrite(ADCSRA,ADPS0,0);
break;
case 2:
bitWrite(ADCSRA,ADPS2,0); bitWrite(ADCSRA,ADPS1,1); bitWrite(ADCSRA,ADPS0,1);
break;
case 3:
bitWrite(ADCSRA,ADPS2,1); bitWrite(ADCSRA,ADPS1,0); bitWrite(ADCSRA,ADPS0,0);
break;
case 4:
bitWrite(ADCSRA,ADPS2,1); bitWrite(ADCSRA,ADPS1,0); bitWrite(ADCSRA,ADPS0,1);
break;
case 5:
bitWrite(ADCSRA,ADPS2,1); bitWrite(ADCSRA,ADPS1,1); bitWrite(ADCSRA,ADPS0,0);
break;
case 6:
bitWrite(ADCSRA,ADPS2,1); bitWrite(ADCSRA,ADPS1,1); bitWrite(ADCSRA,ADPS0,1);;
break;
}
//Analog Input A0 ADMUX=(1<<ADLAR)|(0<<REFS1)|(1<<REFS0)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
muestreo=muestreo/3;
// Lectura de datos
if (muestreo <3 br="" muestreo="" nbsp="" turbo="">
ycal = micros();
y[0] = analogRead(A0);
y[1] = analogRead(A0);
y[2] = analogRead(A0);
y[3] = analogRead(A0);
y[4] = analogRead(A0);
y[5] = analogRead(A0);
y[6] = analogRead(A0);
y[7] = analogRead(A0);
y[8] = analogRead(A0);
y[9] = analogRead(A0);
y[10] = analogRead(A0);
y[11] = analogRead(A0);
y[12] = analogRead(A0);
y[13] = analogRead(A0);
y[14] = analogRead(A0);
y[15] = analogRead(A0);
y[16] = analogRead(A0);
y[17] = analogRead(A0);
y[18] = analogRead(A0);
y[19] = analogRead(A0);
y[20] = analogRead(A0);
y[21] = analogRead(A0);
y[22] = analogRead(A0);
y[23] = analogRead(A0);
y[24] = analogRead(A0);
y[25] = analogRead(A0);
y[26] = analogRead(A0);
y[27] = analogRead(A0);
y[28] = analogRead(A0);
y[29] = analogRead(A0);
y[30] = analogRead(A0);
y[31] = analogRead(A0);
y[32] = analogRead(A0);
y[33] = analogRead(A0);
y[34] = analogRead(A0);
y[35] = analogRead(A0);
y[36] = analogRead(A0);
y[37] = analogRead(A0);
y[38] = analogRead(A0);
y[39] = analogRead(A0);
y[40] = analogRead(A0);
y[41] = analogRead(A0);
y[42] = analogRead(A0);
y[43] = analogRead(A0);
y[44] = analogRead(A0);
y[45] = analogRead(A0);
y[46] = analogRead(A0);
y[47] = analogRead(A0);
y[48] = analogRead(A0);
y[49] = analogRead(A0);
y[50] = analogRead(A0);
y[51] = analogRead(A0);
y[52] = analogRead(A0);
y[53] = analogRead(A0);
y[54] = analogRead(A0);
y[55] = analogRead(A0);
y[56] = analogRead(A0);
y[57] = analogRead(A0);
y[58] = analogRead(A0);
y[59] = analogRead(A0);
y[60] = analogRead(A0);
y[61] = analogRead(A0);
y[62] = analogRead(A0);
y[63] = analogRead(A0);
y[64] = analogRead(A0);
y[65] = analogRead(A0);
y[66] = analogRead(A0);
y[67] = analogRead(A0);
y[68] = analogRead(A0);
y[69] = analogRead(A0);
y[70] = analogRead(A0);
y[71] = analogRead(A0);
y[72] = analogRead(A0);
y[73] = analogRead(A0);
y[74] = analogRead(A0);
y[75] = analogRead(A0);
y[76] = analogRead(A0);
y[77] = analogRead(A0);
y[78] = analogRead(A0);
y[79] = analogRead(A0);
y[80] = analogRead(A0);
y[81] = analogRead(A0);
y[82] = analogRead(A0);
y[83] = analogRead(A0);
y[84] = analogRead(A0);
y[85] = analogRead(A0);
y[86] = analogRead(A0);
y[87] = analogRead(A0);
y[88] = analogRead(A0);
y[89] = analogRead(A0);
y[90] = analogRead(A0);
y[91] = analogRead(A0);
y[92] = analogRead(A0);
y[93] = analogRead(A0);
y[94] = analogRead(A0);
y[95] = analogRead(A0);
y[96] = analogRead(A0);
y[97] = analogRead(A0);
y[98] = analogRead(A0);
y[99] = analogRead(A0);
y[100] = analogRead(A0);
y[101] = analogRead(A0);
y[102] = analogRead(A0);
y[103] = analogRead(A0);
y[104] = analogRead(A0);
y[105] = analogRead(A0);
y[106] = analogRead(A0);
y[107] = analogRead(A0);
y[108] = analogRead(A0);
y[109] = analogRead(A0);
y[110] = analogRead(A0);
y[111] = analogRead(A0);
y[112] = analogRead(A0);
y[113] = analogRead(A0);
y[114] = analogRead(A0);
y[115] = analogRead(A0);
y[116] = analogRead(A0);
y[117] = analogRead(A0);
y[118] = analogRead(A0);
y[119] = analogRead(A0);
y[120] = analogRead(A0);
y[121] = analogRead(A0);
y[122] = analogRead(A0);
y[123] = analogRead(A0);
y[124] = analogRead(A0);
y[125] = analogRead(A0);
y[126] = analogRead(A0);
y[127] = analogRead(A0);
mx= (micros() - ycal);
}
else { // muestreo con rapidez alta
ycal = micros();
for ( punto = 0; punto <= 127; punto++ ) {
y[punto]=analogRead(A0);
delayMicroseconds(muestreo);
}
mx= (micros() - ycal);
}
sensor = mx; // tpo muestreo
} // fin muestreo os. seg arduino
else { // muestreo rapidez media
mx=micros();
ycal=9*(muestreo-256); // calibrado tiempo
for ( punto = 0; punto <= 127; punto++ ) { //muestreo pinA0 arduino maestro
x=1;
y[punto] = analogRead(A0);
retardo0();
}
sensor= (micros()-mx);
} // fin osciloscopio
/// Estimación frecuencia f= picos/tpo muestreo
mx=0;
for ( punto = 0; punto <= 127; punto++ ) {
mx=max(mx,y[punto]);
}
fc = 0;
mx = mx*.9 ; // Pico > 10%
for ( punto = 0; punto <= 127; punto++ ) {
if ( (mx < y[punto]) && (mc == 0)) {
fc = fc + 1;
mc = 1;
}
if (y[punto] < mx) {
mc = 0;
}
}
} // <-- br="" cierre="" nbsp="" osciloscopio="">
else { // monitoreo del pin A0
monitor=1;
mx=millis();
y[128]=0; //media total
x=100;
y[127]=analogRead(A0);
retardo();
ycal=0;
for ( punto = 0; punto <= 126; punto++ ) {
y[punto]=y[punto+1];
ycal=ycal+y[punto];
}
mx=millis()-mx;
y[128]=(ycal+y[127])/128;
} // cierre de monitoreo
/// Dibujar
do {
draw();
} while ( u8g.nextPage() );
// delay(5000); // Para congelar imagen entre muestreo y muestreo. Puede ser interesante controlar este parametro mediante potenciómetro.
}
void retardo0() // retardo osciloscopio arduino maestro
{
if (x
x=x+2;
retardo0();
}
}
void retardo() // retardo monitor
{
if (x<((30*(analogRead(A1)-512)))) {
y[127]=((analogRead(A0))+y[127])/2;
x=x+1;
retardo();
}
}
/////////////////// GRAFICA
void draw(void) {
// graphic commands to redraw the complete screen should be placed here
// u8g.drawFrame(0,0,128,56); //marco exterior
for ( punto = 21; punto <= 106; punto = punto + 42 ) { // punto vertical cada 1V
u8g.drawPixel(punto, 10); u8g.drawPixel(punto, 21); u8g.drawPixel(punto, 32); u8g.drawPixel(punto, 43);
}
u8g.setFontPosTop();
// Grafica de la onda
y3 = 55 - 27 * float(y[0]) / 512; /// 54/1024
for ( punto = 1; punto <= 127; punto++ ) {
ycal = 55 - 28 * float(y[punto]) / 512; /// 54/1024
u8g.drawLine(punto - 1, y3, punto, ycal);
y3 = ycal;
}
// Leyenda
u8g.setFont(u8g_font_04b_03);
u8g.setPrintPos(0, 56);
if (monitor==1){
u8g.print(String(float(y[127])*5/1024) +"V. /"+ String(float(.19+mx/1000)) + " Seg. Med: "+String(float(y[128])*5/1024)+"V."); /// x5V
}
else {
u8g.print( String(float((sensor+.5)/1000)) + " mSeg. /Estm: " + String(long(float(1000000*fc/(sensor+.5) ))) + " Hz ");
}
}
int analogReadFast()
{
ADCSRA|=(1<<ADSC);
// ADSC is cleared when the conversion finishes
while (bit_is_set(ADCSRA, ADSC));
return ADCH;
}
No hay comentarios:
Publicar un comentario