MATLAB Answers

0

I am trying to convert this for loop from matlab to C. Could someone please help

Asked by Kay Wonderley on 10 Apr 2018
Latest activity Edited by Guillaume
on 11 Apr 2018
% variables
Fs = 2000; % Sampling frequency
T = 1/Fs; % Sampling period
L = 4000; % Length of signal
t = (0:L-1)*T; %time samples
A=[16 18 28 33 38 41 59 43 40 58];% Amplitude of noise in dBA (refer to the measurements from consultant)
forigin=[25 31.5 40 50 63 80 100 125 160 200];% Frequency of the noise components (refer to the measurements from consultant)
S=zeros(1,length(t));% This will be the signal representing transformer noise, in your case, it will be the sound created from exciter
for k=1:length(A)
S = S+10^(A(k)/20)*sin(2*pi*forigin(k)*t);%Creating the transformer noise from the amplitude and frequency components, in your case, it will be the sound created from exciter
end
It is implementing the for loop to C.
I have implemented the variables and the "t" values so far.
Thanks any one who can help
Kay

  2 Comments

I have implemented the variables and the "t" values so far.
Then show us that bit, as the loop will depends on how they are declared.
Hi Guillaume, I am doing this on arduino mega and have been printing out the values of "t". So far I am checking the from the start if i am getting the correct values
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
int L = 4000;
//double t [4000];
//int A [10] = {16 18 28 33 38 41 59 43 40 58}; // an integer array of 10 elements intitialised with values
//double forigin [10] = {25.0 31.5 40.0 50.0 63.0 80.0 100.0 125.0 160.0 200.0}; // a double array of 10 elements intitialised with values
}
void loop()
{
// put your main code here, to run repeatedly:
int Fs = 2000;
double T = 1/(double)Fs;
double t[40]; /* t is an array of 4000 integers */
int i;
int j;
for ( i = 0; i < 40; i++ )/* initialize elements of array t to 0 */
{
t[i] = +(double) i*T; /* set element at location i to i*T */
}
for (j = 0; j < 40; j++ ) /* output each array element's value */
{
//Serial.println("Element[%f] = %f\n", j,(float) t[j] );
//printf( " %f\n", t[j] );
Serial.print(t[j],15);
Serial.println("");
delay(500);
}
}

Sign in to comment.

1 Answer

Answer by Guillaume
on 10 Apr 2018
Edited by Guillaume
on 10 Apr 2018
 Accepted Answer

Note: It's been ages since I've written any C code, and even then it was mostly C++ not C. Expect some bugs.
First you'll have to include the math library whatever that is on Arduino. Usually, it's math.h, so:
#define _USE_MATH_DEFINES // to force M_PI to exist
#include <math.h> //for pow, sin and M_PI
The main difficulty with the matlab code is that the operation on S is vectorised which is not an option in C, you have to convert that into a loop, hence you'll have a double for loop.
I would recommend that you name the size of the arrays either using a #define or a variable:
#define TSIZE 40 //or 4000
#define ASIZE 10 //for A and forigin
or
int TSIZE = 40;
int ASIZE = 10;
and use that for all your array declaration
double t[TSIZE];
double A[ASIZE] = {16 18 28 33 38 41 59 43 40 58}; //makes life easier if it's declared as double
double forigin[ASIZE] = {25.0 31.5 40.0 50.0 63.0 80.0 100.0 125.0 160.0 200.0};
//... code to fill t
On to the S calculation:
double S[TSIZE];
int i, k;
//initialise S to 0
for (i = 0; i < TSIZE; ++i) S[i] = 0;
//implement the for k=1:length(A)
for (k = 0; i < 10; ++i){
//devectorise the S calculation
for (i = 0; i < TSIZE; ++i){
S[i] = S[i] + pow(10, A[k]/20) * sin(2*M_PI*forigin[k]*t[i]);
}
}
edit: You could move the calculation of pow(10, A[k]/20) out of the i loop since it only depends on k.

  8 Comments

"The k value is not incrementing from whaI can see".
Indeed, because there is a bug in the loop implementation. It should have been
for (k = 0; k < 10; ++k){
or even better
for (k = 0; k < ASIZE; ++k){
instead of
for (k = 0; i < 10; ++i){
As said, expect bugs! I don't have a compiler to test the code.
Hi thanks again. I have made the changes but k is not incrementing. K does not seem to be able to see the forigin loop and I don't quite know how.I would appreciate any iseas, or point me to the right place. Kind regards Kay
#define _USE_MATH_DEFINES // to force M_PI to exist
#include <math.h> //for pow, sin and M_PI
#define ASIZE 10 //for A
#define TSIZE 40 //or 4000
int Fs = 2000;
int L = 40;
double A[ASIZE] = {16, 18, 28, 33, 38, 41, 59, 43, 40, 58};
double forigin[ASIZE] = {25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, 125.0, 160.0, 200.0};
double S[TSIZE];
double t[TSIZE];
double T = 1/(double)Fs;
int i,k, j;
//int k = 10;
double apow = pow(10, A[k]/20);
void setup() {
Serial.begin(9600);
}
void loop()
{
for ( i = 0; i < TSIZE ; i++ ) /* initialize elements of array t to 0 */
{
t[i] = (double) i*T; /* set element at location i to i*T */
}
for (j = 0; j < TSIZE; j++ ) /* output each array element's value */
{
// Serial.print(t[j],15);
// Serial.println("");
// delay(500);
}
//initialise S to 0
for (i = 0; i < TSIZE; ++i) //S[i] = 0;
//implement the for k=1:length(A)
for (k = 0; i < ASIZE; ++k){
//devectorise the S calculation
for (i = 0; i < TSIZE; ++i){
S[i] = S[i] + pow(10, A[k]/20) * sin(2*M_PI*forigin[k]*t[i]);
Serial.print(k);
Serial.println("");
delay(500);
//}
After pasting code, select all the code then press the {}Code button to format it appropriately.
for (i = 0; i < TSIZE; ++i) //S[i] = 0;
The allocation should not be commented. In particular, since the ; is commented I'm not sure what the scope of the loop is.
for (k = 0; i < ASIZE; ++k){
Well, this time it's your fault. It's not what I wrote. It must be k < ASIZE. As you've written it then yes, the k loop will only execute once since at the 2nd iteration i is TSIZE.

Sign in to comment.