Para hacer un osciloscopio en un entorno matlab, para la adquisición de datos en el lado arduino, cuando se utiliza el analogRead()
incorporado, funciona bien, pero con una tasa de muestreo muy baja, se observa claramente el aliasing. Eso también, muestreo no uniforme. Por lo tanto, enumerar los inconvenientes:
- Velocidad de datos muy lenta, incluso si se envía con 115200 baudrate,
- Aliasing
- Muestreo no uniforme
Porlotanto,parasuperarloanterior,seusóADCenelmododeejecuciónlibre,con16comofactordepreescalado,yporlotantounatasademuestreode76.9KHz(contandocadaADCcomo13ciclosdereloj).Porlotanto,losdatossemuestreanuniformementeahora.Tambiénesbastanterápido,debidoalmuestreo,yseobserva.Elúnicoproblemaqueexisteahoraesquelasalidatieneunruidoespecífico.Losdatosquesemuestreansonunaformadeondadecorrientesinusoidalde50HzporelsensordecorrienteACS712.Superponelaformadeondadelacorrienteinstantáneaconunsesgode2.5V.Porlotanto,cuandolaseñalnoestápresente,seobservaunvoltajeconstantede2.5V,porlotanto,512,debidoalmapeoalrangode255..127.Peroenelcasodelmododefuncionamientolibre,juntocon127,191,63soloseobservan.Ytambiénsepuedeverquecasi127=63*2,y191=63*3.Ycuandoexistelaformadeondaactual,estámuydistorsionada,peroesperceptiblequenoeslaseñalanteriordesolo127,191,63.Enlagráficadeabajo,lacorrientesepasadesde33.5seg.
No puedo entender este ruido estructurado observado. ¿Cuál puede ser la razón? Una vez leí, los últimos dos bits de MSB se vuelven ruidosos a esta velocidad de muestreo, pero entonces, ¿cómo 127 saltaría a 191. ¿Por qué se agregan 63 restas en cada instante?
Entiendo que la razón para el muestreo no uniforme ahora es debido a Serial.print()
, cuyas interrupciones están obstruyendo las interrupciones ADC, pero no entiendo la razón detrás del ruido observado.
A continuación se muestra el código subido en arduino. Los datos en serie se leen desde matlab mediante la función fread()
.
long t1=0,ts1=0,ts2=0;
int aval=0, val=0;
void setup() {
TIMSK0 = 0x00; // disable timer (causes anoying interrupts)
DIDR0 = 0x3F; // digital inputs disabled
ADMUX = 0x40; // measuring on ADC0, right adjust, AREF reference
ADCSRA = 0xAC; // AD-converter on, interrupt enabled, prescaler = 16
ADCSRB = 0x00; // AD channels MUX on, free running mode
bitWrite(ADCSRA, 6, 1); // Start the conversion by setting bit 6 (=ADSC) in ADCSRA
sei();
Serial.begin(115200);
t1=millis();
}
ISR(ADC_vect)
{
aval = ADCL;
aval += ADCH << 8;
}
void loop() {
val = map(aval, 0, 1023, 0, 255);
Serial.write(val);
delay(10);
}