Tras comprobar las limitaciones de modificar el prescaler en el arduino con casi todos sus pines analógicos trabajando, pensé en el otro pequeñín que tenía guardado en un cajón que podía ocuparse de hacer el muestreo de la señal, enviarselo al otro via serie que sería el encargado de los cálculos y la representación gráfica.
Al fin y al cabo los osciloscopios basados en arduino "más" decentes que he visto en internet funcionan así, aunque también hay otra opción con un solo arduino: conectarlos en serie.
De esta manera he logramos logrado una resolución de 6useg./pixel o lo que es lo mismo todo el ancho de pantalla menor de 1 milisegundo, con el potenciometro podemos variar la duración del muestreo hasta 200 mSeg. a partir de ahí el comportamiento del programa cambia y monitorea el valor de la señal.
El sketch viene preparado, descomentando una de las líneas finales del void(loop), para insertar un potenciometro al pin A7 y estabilizar la imagen, sobre todo en las frecuencias medias.
Una vez hecho el muestreo se envían al maestro los datos a través del puerto serie, siendo el último dato el tiempo invertido en el muestreo, para que este los analice y represente en el lcd.
La lectura de la frecuencia es sólo una estimación y no es el propósito de este programa, aunque es bastante aproximada si vemos varias ondas en la pantalla,
Nuestro osciloscopio sólo admite valores de entrada entre 0 y +5V, y otros valores lo pueden dañar, así que para visualizarlos hay que usar divisores resistivos o zener.
Para que funcionen los sketch hay que tener instalada la librería U8glib.
Las conexiones son practicamente las mismas que en el osciloscopio anterior, con algunas pequeñas modificaciones para posibilitar la comunicación entre arduinos.
Los arduinos se conectan entre sí a través de los pines Tx y Rx con un cable cruzado, también deben compartir la masa, La señal se escanea a través del pin A0 del arduino esclavo.
Sketch 1. Arduino maestro (conectado al lcd) 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 x;
int y[130];
boolean monitor;
int y2;
unsigned long ycal;
byte punto;
byte y3;
float mx;
byte mc;
byte fc;
void setup(void) {
Serial.begin(115200);
}
void loop(void) {
u8g.firstPage();
// Envio del tpo de muestreo
sensor = analogRead(A1)/2;
if (sensor < 256) { // Osciloscopio
monitor=0;
if ( sensor <64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo="">
Serial.write(byte(sensor));
// Lectura de datos
for ( punto = 0; punto <= 129; punto++ ) {
while( Serial.available()==0){
}
y[punto] = Serial.read();
}
sensor = (y[128]); // tpo muestreo
} // fin muestreo os. seg arduino
else { // muestreo propio arduino
y[129]=0;
mx=millis();
ycal=8*(sensor-64); // calibrado tiempo
for ( punto = 0; punto <= 127; punto++ ) { //muestreo pinA0 arduino maestro
x=1;
y[punto] = analogRead(A0);
// delayMicroseconds(ycal);
retardo0();
}
sensor= (millis()-mx)*4;
for ( punto = 0; punto <= 127; punto++ ) {
y[punto] = y[punto]/4;
y[129]=max(y[129],y[punto]);
}
} // fin osciloscopio arduino maestro
/// Estimación frecuencia f= picos/tpo muestreo
fc = 0;
mx = y[129]*.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)/4;
retardo();
for ( punto = 0; punto <= 126; punto++ ) {
y[punto]=y[punto+1];
y[128]=y[128]+y[punto];
}
mx=millis()-mx;
y[128]=y[128]/128;
} // cierre de monitoreo
/// Dibujar
do {
draw();
} while ( u8g.nextPage() );
// delayMicroseconds(analogRead(A7)*50); // Para congelar imagen entre muestreo y muestreo conviene 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)/4)+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]) / 128; /// 54/1024
for ( punto = 1; punto <= 127; punto++ ) {
ycal = 55 - 28 * float(y[punto]) / 128; /// 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/255) +"V. /"+ String(float(.17+mx/1000)) + " Seg. Med: "+String(float(y[128])*5/255)+"V."); /// x5V
}
else {
u8g.print( String(float((sensor+.5)/4)) + " mSeg. /Estm: " + String(long(float(fc / (sensor+.5) * 4000))) + " Hz ");
}
}
<64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo=""><-- br="" cierre="" nbsp="" osciloscopio="">
<64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo=""><-- br="" cierre="" nbsp="" osciloscopio="">
<64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo=""><-- br="" cierre="" nbsp="" osciloscopio="">-->64>
<64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo=""><-- br="" cierre="" nbsp="" osciloscopio="">-->64><64 arduino="" br="" con="" nbsp="" osciloscopio="" segundo=""><-- br="" cierre="" nbsp="" osciloscopio="">
-->64>
Sketch 2. Arduino esclavo ( encargado de la obtención de datos.) Descargar
void setup() {
Serial.begin(115200);
}
//////
void loop(void) {
byte punto;
byte y[130];
int sensor;
unsigned long ycal;
// Muestreo
while( Serial.available()==0){
}
sensor=Serial.read();
//Prescaler
//ADPS2 - ADPS1 - ADPS0 - Division Factor
//0 - 0 - 0 ->2
//0 - 0 - 1 ->2
//0 - 1 - 0 ->4 >
//0 - 1 - 1 ->8 ***
//1 - 0 - 0 ->16
//1 - 0 - 1 ->32
//1 - 1 - 0 ->64
//1 - 1 - 1 ->128
// A partir de 4 funciona bien, el 2 distorsiona mucho. Cuanto más subimos el osciloscopio es más lento pero más preciso
switch(byte(1+6*sensor/64))
{
case 0: // =2 distorsionado
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 3:
bitWrite(ADCSRA,ADPS2,0); bitWrite(ADCSRA,ADPS1,1); bitWrite(ADCSRA,ADPS0,1);
break;
case 4:
bitWrite(ADCSRA,ADPS2,1); bitWrite(ADCSRA,ADPS1,0); bitWrite(ADCSRA,ADPS0,0);
break;
case 5:
bitWrite(ADCSRA,ADPS2,1); bitWrite(ADCSRA,ADPS1,0); bitWrite(ADCSRA,ADPS0,1);
break;
case 6:
bitWrite(ADCSRA,ADPS2,1); bitWrite(ADCSRA,ADPS1,1); bitWrite(ADCSRA,ADPS0,0);
break;
case 7:
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);
sensor=sensor*1.2;
if (sensor ==0) {
/// MUESTREO turbo
ycal = micros();
//
y[0] = analogReadFast();
y[1] = analogReadFast();
y[2] = analogReadFast();
y[3] = analogReadFast();
y[4] = analogReadFast();
y[5] = analogReadFast();
y[6] = analogReadFast();
y[7] = analogReadFast();
y[8] = analogReadFast();
y[9] = analogReadFast();
y[10] = analogReadFast();
y[11] = analogReadFast();
y[12] = analogReadFast();
y[13] = analogReadFast();
y[14] = analogReadFast();
y[15] = analogReadFast();
y[16] = analogReadFast();
y[17] = analogReadFast();
y[18] = analogReadFast();
y[19] = analogReadFast();
y[20] = analogReadFast();
y[21] = analogReadFast();
y[22] = analogReadFast();
y[23] = analogReadFast();
y[24] = analogReadFast();
y[25] = analogReadFast();
y[26] = analogReadFast();
y[27] = analogReadFast();
y[28] = analogReadFast();
y[29] = analogReadFast();
y[30] = analogReadFast();
y[31] = analogReadFast();
y[32] = analogReadFast();
y[33] = analogReadFast();
y[34] = analogReadFast();
y[35] = analogReadFast();
y[36] = analogReadFast();
y[37] = analogReadFast();
y[38] = analogReadFast();
y[39] = analogReadFast();
y[40] = analogReadFast();
y[41] = analogReadFast();
y[42] = analogReadFast();
y[43] = analogReadFast();
y[44] = analogReadFast();
y[45] = analogReadFast();
y[46] = analogReadFast();
y[47] = analogReadFast();
y[48] = analogReadFast();
y[49] = analogReadFast();
y[50] = analogReadFast();
y[51] = analogReadFast();
y[52] = analogReadFast();
y[53] = analogReadFast();
y[54] = analogReadFast();
y[55] = analogReadFast();
y[56] = analogReadFast();
y[57] = analogReadFast();
y[58] = analogReadFast();
y[59] = analogReadFast();
y[60] = analogReadFast();
y[61] = analogReadFast();
y[62] = analogReadFast();
y[63] = analogReadFast();
y[64] = analogReadFast();
y[65] = analogReadFast();
y[66] = analogReadFast();
y[67] = analogReadFast();
y[68] = analogReadFast();
y[69] = analogReadFast();
y[70] = analogReadFast();
y[71] = analogReadFast();
y[72] = analogReadFast();
y[73] = analogReadFast();
y[74] = analogReadFast();
y[75] = analogReadFast();
y[76] = analogReadFast();
y[77] = analogReadFast();
y[78] = analogReadFast();
y[79] = analogReadFast();
y[80] = analogReadFast();
y[81] = analogReadFast();
y[82] = analogReadFast();
y[83] = analogReadFast();
y[84] = analogReadFast();
y[85] = analogReadFast();
y[86] = analogReadFast();
y[87] = analogReadFast();
y[88] = analogReadFast();
y[89] = analogReadFast();
y[90] = analogReadFast();
y[91] = analogReadFast();
y[92] = analogReadFast();
y[93] = analogReadFast();
y[94] = analogReadFast();
y[95] = analogReadFast();
y[96] = analogReadFast();
y[97] = analogReadFast();
y[98] = analogReadFast();
y[99] = analogReadFast();
y[100] = analogReadFast();
y[101] = analogReadFast();
y[102] = analogReadFast();
y[103] = analogReadFast();
y[104] = analogReadFast();
y[105] = analogReadFast();
y[106] = analogReadFast();
y[107] = analogReadFast();
y[108] = analogReadFast();
y[109] = analogReadFast();
y[110] = analogReadFast();
y[111] = analogReadFast();
y[112] = analogReadFast();
y[113] = analogReadFast();
y[114] = analogReadFast();
y[115] = analogReadFast();
y[116] = analogReadFast();
y[117] = analogReadFast();
y[118] = analogReadFast();
y[119] = analogReadFast();
y[120] = analogReadFast();
y[121] = analogReadFast();
y[122] = analogReadFast();
y[123] = analogReadFast();
y[124] = analogReadFast();
y[125] = analogReadFast();
y[126] = analogReadFast();
y[127] = analogReadFast();
y[128]= (micros() - ycal)/250;
}
else { // muestreo con retardo
ycal = micros();
for ( punto = 0; punto <= 127; punto++ ) {
y[punto]=analogReadFast();
delayMicroseconds(sensor);
}
y[128]= (micros() - ycal)/250;
}
// ENVIO al otro arduino
for ( punto = 0; punto <= 127; punto++ ) {
y[129]=max(y[129],y[punto]); //Pico
Serial.write(y[punto]);
}
Serial.write(y[128]); Serial.write(byte(y[129]));
y[129]=0; // Pico
}
//Read ADC
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