2

I have code that fetches analog input values from terminals A0, A1 and A2 of an Arduino Mega 2560. When I plot the data, it does not give the desired waveform.

The desired waveform is also measured with a the digital storage oscilloscope.

I was thinking to make use of an Arduino Mega 2560 as an oscilloscope that can have 16 channels, because the DSO has only 4 and for a project, I urgently need 16 channels. Would be great if the community people suggest something.

Data read by Arduino-MATLAB interface

Below is the desired data from the oscilloscope that is measured in parallel to avoid any confusion about the circuit.

Desired data measured parallel by an oscillopse

%This is a script that will plot Arduino analogRead values in real time
%Modified from http://billwaa.wordpress.com/2013/07/10/matlab-real-time-serial-data-logger/
%The code from that site takes data from Serial 

clear all
close all
clc

%User Defined Properties 
a = arduino('Com5')             % define the Arduino Communication port
arduino=serial('COM5','BaudRate',9600);
s1 = serial('COM5');                                                       % Define here YOUR serial port
s1.BaudRate=9600;   


plotTitle = 'Arduino Data Log';  % plot title
xLabel = 'Time (s)';     % x-axis label
yLabel = 'Voltage (V)';      % y-axis label
legend1 = 'Voltage 1'
legend2 = 'Voltage 2'
legend3 = 'Voltage 3'
yMax  = 5                           %y Maximum Value
yMin  = 0                       %y minimum Value
plotGrid = 'on';                 % 'off' to turn off grid
min = 0;                         % set y-min
max = 5;                        % set y-max
delay = .01;                     % make sure sample faster than resolution 

%Define Function Variables
time = 0;
data = 0;
data1 = 0;
data2 = 0;
count = 0;

%Set up Plot
plotGraph = plot(time,data,'-r' )  % every AnalogRead needs to be on its own Plotgraph
hold on                            %hold on makes sure all of the channels are plotted
plotGraph1 = plot(time,data1,'-b')
plotGraph2 = plot(time, data2,'-g' )
title(plotTitle,'FontSize',15);
xlabel(xLabel,'FontSize',15);
ylabel(yLabel,'FontSize',15);
legend(legend1,legend2,legend3)
axis([yMin yMax min max]);
grid(plotGrid);

tic

while ishandle(plotGraph) %Loop when Plot is Active will run until plot is closed

%          dat = readVoltage(a,'A0')* 0.48875855327; %Data from the arduino
%          dat1 = readVoltage(a,'A1')* 0.48875855327; 
%          dat2 = readVoltage(a,'A2')* 0.48875855327;       

         dat = readVoltage(a,'A0')* 1; %Data from the arduino
         dat1 = readVoltage(a,'A1')* 1; 
         dat2 = readVoltage(a,'A2')*1; 
         
         count = count + 1;    
         time(count) = toc;    

         data(count) = dat(1);         
         data1(count) = dat1(1)
         data2(count) = dat2(1)

         %This is the magic code 
         %Using plot will slow down the sampling time.. At times to over 20
         %seconds per sample!
         set(plotGraph,'XData',time,'YData',data);
         set(plotGraph1,'XData',time,'YData',data1);
         set(plotGraph2,'XData',time,'YData',data2);

          axis([0 time(count) min max]);

          %Update the graph
          %pause(delay);
  end

delete(a);

disp('Plot Closed and arduino object has been deleted');`
3
  • 1
    What sketch are you using on the Arduino? Are you using something like Firmata? Where does the readVoltage() function come from? It isn't anywhere in the link, where you modified the code from. From your images it is obvious, that you are sampling way too slow for seeing the wave form.
    – chrisl
    Sep 10, 2020 at 19:15
  • 1
    You are trying to sample at ≈ 12 samp/s a waveform that is around 3 kHz. You must read about the Nyquist–Shannon sampling theorem. Sep 10, 2020 at 19:48
  • why are you sampling 3 channels? ... first determine if one channel can capture the data, then try two channels, etc.
    – jsotola
    Sep 10, 2020 at 21:10

1 Answer 1

3

Your sampling rate is far too low for the signals you are looking at; you're not getting enough data points for drawing something that looks like the original signal.

The Arduino library's analogRead(), while slow, can do better, up to about 9000 samples/s; the ADC in the atmega2560 in free-running mode can do about 75000 samples/s at 8 bits resolution. This would require programming it at the register level.

There is only one ADC, so if you want 16 channels, this leaves about 4700 samples/s for each channel. In that configuration, however, the first measurements aren't valid and the second ones should be used, further reducing the sample rate per channel to about 2300 samples/s.

With a perfect reconstruction filter, this would limit you to measuring signals up to only 1150 Hz.

All this doesn't even consider the time it takes to store or transmit the results.

So, an Arduino Mega 2560 will not do for making a usable 16-channel oscilloscope for your signals; it's not even close.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.