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

### Kay Wonderley (view profile)

on 10 Apr 2018
Latest activity Edited by Guillaume

on 11 Apr 2018

### Guillaume (view profile)

% 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

Guillaume

### Guillaume (view profile)

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 (view profile)

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);
}
}

### Guillaume (view profile)

on 10 Apr 2018
Edited by Guillaume

### Guillaume (view profile)

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.

Guillaume

### Guillaume (view profile)

on 11 Apr 2018
"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){
for (k = 0; i < 10; ++i){
As said, expect bugs! I don't have a compiler to test the code.
Kay Wonderley

### Kay Wonderley (view profile)

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 (view profile)

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.