To make an oscilloscope in matlab environment, for data acquisition on arduino side, when inbuilt analogRead()
is used, it's working fine, but with very low sampling rate, that aliasing is clearly observed. That too, non-uniform sampling. Thus listing out the drawbacks:
- Very slow data rate, even if, sent with 115200 baudrate,
- Aliasing
- Non-uniform sampling
Thus, to overcome above, ADC in free running mode was used, with 16 as prescaling factor, thus 76.9KHz sampling rate (counting each ADC as 13 clock cycles). Thus, data is uniformly sampled now. Also it is quite fast, because of sampling, and is observed. The only problem now exists is, output has a specific noise. The data being sampled is 50Hz sinusoidal current waveform by current sensor ACS712. It overlays instantaneous current waveform over a bias of 2.5V. Thus, when signal is not present, a constant voltage of 2.5V is observed, thus, 512, because of mapping to 255 range.. 127. But in the case of free running mode, along with 127, 191, 63 only are observed. And it can also be seen that nearly 127 = 63*2, and 191 = 63*3. And when current waveform exists, it's highly distorted, but perceptible that it's not the previous signal of just 127, 191, 63. In the below plot, current is passed since 33.5sec.
I am unable to understand this, structured noise. What may be the reason ? I have once read, last two MSB bits get noisy at this sampling rate, but then how would 127, jump to 191. Why is 63 getting added, subtracted at each instant ?
I understand the reason for non-uniform sampling now is because of Serial.print()
, whose interrupts are obstructing the ADC interrupts, but don't understand the reason behind the noise observed.
Following is the code uploaded in arduino. Serial data is read from matlab by fread()
function.
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);
}
millis()
anddelay(10)
working as you've disabled it's interrupt.Serial.write(ADCH);
.