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

2 views (last 30 days)
% 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
Guillaume
Guillaume on 10 Apr 2018
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.
Kay Wonderley
Kay Wonderley on 10 Apr 2018
Edited: Torsten on 10 Apr 2018
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.

Accepted Answer

Guillaume
Guillaume on 10 Apr 2018
Edited: Guillaume on 10 Apr 2018
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
Kay Wonderley
Kay Wonderley on 11 Apr 2018
Edited: Guillaume on 11 Apr 2018
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);
//}
Guillaume
Guillaume on 11 Apr 2018
Edited: Guillaume on 11 Apr 2018
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.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!