ACS712 Current Sensor Data Plot using MATLAB and Arduino - matlab

I am working on a GUI to plot ac712 current data to MATLAB GUI. The problem is I cannot plot the data properly. The plot seems to be triangular and not sinusoidal curve. Also the current values are correct but I think x-axis values are incorrect. Please help.
clear all
clc
a = arduino('com3','uno');
samples = 200
for i = 1:201
x = [0:0.001:2];
y = zeros(1,201);
b = a.readVoltage(0);
y(i) = ((b-2.5)/.234);
i = i+1
pause (0.006)
end
figure(1)
plot(x,y)
Fig. Plot obtained using MATLAB
When I use arduino only for the same, the values for current are as follows:
0.46
-0.69
1.04
-0.94
0.81
-0.29
-0.06
0.71
-0.83
1.08
-0.81
0.62
0.04
-0.31
0.87
-0.87
1.1
-0.67
0.37
0.27
-0.56
1.02
-0.92
0.94
-0.46
0.08
0.52
-0.71
1.04
which when plotted using Excel is as follows:
Fig. Plot obtained with Arduino current data and x axis values as: 1-29

Are the time scales of both graphs the same?
What is the frequency of the signal you are trying to read?
Because the ACS712 uses chopper stabilization, the output signal is similar to your plot.
You may need to add or change the capacitor between the filter input pin and ground as shown on the typical application figure on the front page of the ACS712 datasheet.

Related

Unable to Plot a C.T. Signal Graph in MATLAB

I am trying to plot the C.T. Signal Gaph (x(t)) in MATLAB for 0<=t<0.2 ms as mentioned in the below given figure. I have written the following code, but, not sure what should be the step size for time t in the graph. Any help would be highly appreciated:) Thanks!
t = 0:0.00002:0.0002;
f = 10000;
x = 4*sin(2*pi*f*t);
figure;
plot(t,x);
There seems to be a misstatement in the text. Ts is the sampling period, whereas the sampling rate is the inverse of the sampling period, Fs=1/Ts. With a Ts of 0.02 ms, that means the sampling rate is actually 50 kHz.
What's happening in the graph is that a continuous function, x(t) is being sampled by multiplying it with a pulse train, p(t). The p(t) function is composed of an infinite number of (Dirac) delta functions equally spaced by Ts seconds and goes on for infinity. The input also goes on for forever, since sin(t) is defined for all t. The concept here is to understand that by multiplying x(t) by p(t), you're getting samples of x(t) spaced out at Ts intervals.
Because both signals are infinite, you should just pick a meaningful time range for the analysis you wish to perform. In this case, it's educational, so just pick maybe a few cycles of the incoming frequency so you can see the samples. At 10kHz, the input should repeat every 0.1 ms. You should expect to see 5 samples per cycle of the sine wave (0.1 ms / (0.02 ms/sample) = 5 samples). I'd just plot it from -0.2 ms to 0.2 ms to see a few of the cycles. By adding '-o' as the plot option, you'll see 'o' markers wherever the samples were taken.
t = -0.0002:0.00002:0.0002;
f = 10000;
x = 4*sin(2*pi*f*t);
figure;
plot(t,x,'-o');
You can try changing the sampling period. For instance, try dividing it by 10.
t = -0.0002:0.000002:0.0002;
f = 10000;
x = 4*sin(2*pi*f*t);
figure;
plot(t,x,'-o');

Curve fitting with an integral function involved

I have a 2 parameter model that includes an integral function and I´m quite lost how to solve this.
My data consists of a set of given molecule sizes, r_m, and a calculated response, K.
The theoretical model is a function of this molecule size, r_m, but also involves the integral of the Gaussian distribution (to make it simpler) of the pore size distribution of an adsorbent material. So it has the following form:
r_p and s_p are the 2 parameters.
So far I've tried to solve this in MATLAB based on the following post:
https://de.mathworks.com/help/optim/examples/nonlinear-data-fitting.html
and this is my code so far:
Data = ...
[0.5 1
1.1 0.83
1.6 0.74
2.2 0.55
2.5 0.28
3.5 0];
r = Data(:,1);
K_exp = Data(:,2);
F = #(x,xdata) quad( (exp(-1/2.*((xdata - x(1))/x(2)).^2).*(1 - (xdata(1)/xdata).^2)),xdata(1),120)./quad(exp(-1/2.*((xdata - x(1))/x(2)).^2,0,120) ; ;
x0 = [6 0.5] ;
[x,resnorm,~,exitflag,output] = lsqcurvefit(F,x0,r,K_exp)
Does this adaption make sense? I'm not sure on the one hand how to properly include an integral into the fitting syntax, and on the other hand I don´t know how to properly tell MATLAB that the lower bound of integration for the numerator should be the size of the molecule, r_m. What I'm imaging is that xdata is some sort of vector for the size, r, as in the example in the link for time, t. However, the lower limit of integration is not fixed but varies for each of the points I want to fit.
Any help is greatly appreciated!

Plotting the reciprocal of a sine wave in MatLab

I'm having difficulties trying to plot the reciprocal of a basic sine wave within MatLab. The tutorial I'm following (not a MatLab tutorial) is plotting it by hand by placing a few points between each vertical asymptote to give you an idea of what the graph will look like. I've tried using MatLab's csc() function, and the graph when plotted along side x is nothing like the drawn example. The drawn example from 0 to pi looks similar to a big U and from pi to 2*pi is a negative version (upside down). Here is all the different combinations of code I've tried:
x = 0:0.01:100;
y = 5*csc(x); % amplitude of -5 to 5
plot(x,y)
Then I tried:
x = 0:0.01:100;
y = 1 / 5*sin(x); % amplitude of -5 to 5
plot(x,y)
Both results are dramatically different. I was wondering if using the vector x was okay as I was under the impression after one of my previous posts that the standard MatLab trig functions are setup to take radians rather than degrees?
Can you try this -
x = 0 : 0.01 : 2*pi;
y = csc(x);
plot(x,y)
ylim([-10, 10])
Is that what you expected?

PSD estimation via FFT

I estimate Power Spectral Density (PSD) for Gaussian monopulse in UWB band. I have two codes, using fft. But there is a problem with y axes, since I don't know its dimension (I need PSD in dBm/MHz). And also it should be a mistake in the first code, since it shows only one value at the y axes.
Code1
fs=1e11;
g=0.1e-9;
tmax=1e-9;
fftl=2048;
t=(-tmax:1./fs:tmax)';
s=t./(g.^3.*sqrt(2.*pi)).*exp(-t.^2./(2.*g.^2))./2.5e19;
figure(1)
plot(t,s);
xlabel('Time, s');
ylabel('Amplitude, V');
ffts=abs(fft(s,fftl));
ffts=2.*ffts./fftl;
fftp=abs(ffts.*conj(ffts))./2;
fftps=(fftp-30)./1e-6;
f=0:fs./fftl:fs./2-fs./fftl;
figure(2)
plot(f,fftps(1:length(f))),grid;
xlabel('Frequency, Hz');
Code2
fs=1e11;
g=0.1e-9;
tmax=1e-9;
t=(-tmax:1./fs:tmax)';
s=t./(g.^3.*sqrt(2.*pi)).*exp(-t.^2./(2.*g.^2))./2.5e19;
figure(1)
plot(t,s);
xlabel('Time, s');
ylabel('Amplitude, V');
S=fft(s,8192);
f=fs.*(0:4095)./8192;
Pss=S.*conj(S)./8192;
figure(2)
plot(f,Pss(1:4096));
Thank you so much for any help!
Your second plot should give you a plot with units V^2/Hz.
dBm units are measure of power relative to 1 mW, so you have to know the impedance of your measurement.
So to get to mW/Hz you would want to multiply by 1e6/R, where R is your impedance. Then take 10*log10 of the result and you have dBm/Hz.

How do I find the average slope of a 3-D surface? MatLab

`2.4 2.34 2.21 1.90 1.4 0.83 0
2.34 2.42 2.16 1.79 1.3 0.7 0
2.21 2.16 1.99 1.64 1.16 0.51 0
1.90 1.79 1.64 1.30 0.75 0 0
1.4 1.34 1.16 0.75 0 0 0
0.83 0.75 0.51 0 0 0 0
0 0 0 0 0 0 0
`
This is what my matrix looks like at one point in time and Id like to calculate the average slope or gradient of the surface( An indicator of steepness).
It seems like MatLab should have a built in function for this sort of thing but I can find one. I have also tried a code that I wrote but it is not accurate.
Best,
Abid
the gradient is vectorial, so you can treat the two dimensions separately.
Calculating the gradient consists of calculating the first derivative to every parameter of the function. In the discrete domain, this can be done by taking the finite differences: http://en.wikipedia.org/wiki/Finite_difference
If you want it exact and calculate the gradient at each point, you can't just take the forward or backward differences, because at the edge, you don't always have a forward (or backward) point.
But I think if you just want the mean of the gradient, you don't have to bother with the edges and you can just compute the finite differences for the central points between your original points by using diff:
dx = diff(data,1,1);
dy = diff(data,1,2);
mean_gradient = [mean(dx(:)) mean(dy(:))]
assuming equal spacing of the parameters of cours, else you'll have to divide dx and dy by the step sizes.
For the data you provided, this results in:
mean_gradient =
-0.26381 -0.26381
which matches the plot you've made that shows that the function is monotonically decreasing and symmetric in the parameters.
One way to do this is to perform multiple linear regression, for example by using regress.
A two-dimensional regression is a best-fit plane, from which you can calculate a slope value. The link has a nice example with code and a plot of the results.