Show Posts
Pages: [1] 2
1  Using Arduino / Installation & Troubleshooting / Re: Arduino IDE 1.5.3 doesn't work like 1.5.2 on: September 11, 2013, 10:37:33 am
A small clarification:
..of course the problem it's not visualmicro. Once i found the problem, I extracted the code portion above and compiled directly into ArduinoIDE..
2  Using Arduino / Installation & Troubleshooting / Re: Arduino IDE 1.5.3 doesn't work like 1.5.2 on: September 11, 2013, 10:32:31 am
Hi cmaglie, sorry but I've no updates. I'm working on my thesis and I can't loose my head rigth now trying different combinations of arduinoIDE and visualmicro and debugging results. I've gone back to arduinoIDE 1.5.2 and visualmicro 1308.04 that worked pretty fine.
I don't know why, but 1.5.3 is unable to have a SPI connection when specifying SS pin. If I ground CS on the ADC and I use SPI without SS pin it works. Now since I have two SPI devices and I need to manage them, I've gone back to a working configuration ..
3  Using Arduino / Installation & Troubleshooting / Re: Arduino IDE 1.5.3 doesn't work like 1.5.2 on: September 11, 2013, 09:05:22 am
I installed 1.5.3 five days ago but now I see a new version has been released, may be with 1.5.4 will work.. Thanx anyway
4  Using Arduino / Installation & Troubleshooting / Arduino IDE 1.5.3 doesn't work like 1.5.2 on: September 11, 2013, 07:49:34 am
Hi guys, I'm having some troubles compiling with new IDE 1.5.3. The same code below, compiled with 1.5.2 works, but when I compile with 1.5.3 it doesn't work. It stops on first iteration receiving no byte from SPI. Do you have any idea?

Code:

#include <SPI.h>
void setup() {
  // put your setup code here, to run once:
Serial.begin(115200); // Start Serial Communication
Serial.println("Ready");
        pinMode(9,OUTPUT);
        digitalWrite(9,HIGH); // Conversion pin high
        pinMode(6,OUTPUT);
        digitalWrite(6,LOW);                                                                   // Power up
SPI.begin(10); // Start SPI Communication on CS pin 10
SPI.setBitOrder(10,MSBFIRST); // Set Bit Order MSB
SPI.setClockDivider(10,255); // Set Oscillator to SPI Clock divider
SPI.setDataMode(10,SPI_MODE0);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(9,LOW); // Start ADC conversion
        delayMicroseconds(50);
digitalWrite(9,HIGH); // Stop ADC conversion
 
byte response1 = SPI.transfer(10,0x00, SPI_CONTINUE); // Receive  first byte (1/2 16 bit)
byte response2 = SPI.transfer(10,0x00); // Receive second byte (2/2 16 bit)
   
short int value = (((uint32_t) response1) << 8 | response2); // Merge bytes
Serial.println(value);
  delay(100);
}

5  Products / Arduino Due / Re: ArduinoDUE - FloatingPointVS Integer math on: August 26, 2013, 05:18:46 pm
Thanks for suggestions. Now it's quite late for me, so I'm going to sleep. Tomorrow I'll get the execution time for each step inside the code and I'll post the output.
I don't know if it could be useful, but I'm using Atmel Studio Framework with VisualMicro plugin to compile and flash the code. Goodnight
6  Products / Arduino Due / Re: ArduinoDUE - FloatingPointVS Integer math on: August 26, 2013, 04:51:12 pm
Hi schwingkopf,
I've used almost no division in my code but only multiplications and sums, except some average calculation. In the integer math version there are only multiplication between int32 and float32, while in double version there are multiplication between double64..
7  Products / Arduino Due / Re: ArduinoDUE - FloatingPointVS Integer math on: August 26, 2013, 04:41:27 pm
I forgot the statistics() function:
Code:
void statistics()
{
// Mean value
unsigned int meanSum = 0;
for (int i=0;i<Fs*T/D;i++)
meanSum += polyResult[i];

meanValue = (double)meanSum/(Fs*T/D); // Averaging reduces quantization noise by 1/sqrt(K) |K=1000 => 30 dB => 5 LSBs

// Standard deviation value
double stdSum = 0;
for (int i=0;i<Fs*T/D;i++)
stdSum += ((double)polyResult[i]-meanValue)*((double)polyResult[i]-meanValue);

stdValue = sqrt(stdSum/(Fs*T/D-1));
}

8  Products / Arduino Due / Re: ArduinoDUE - FloatingPointVS Integer math on: August 26, 2013, 04:23:56 pm
And this is the double math version:

Code:
#define nelems(x) sizeof(x)/sizeof(*x)
const int Fs = 5000; // Sample Rate
const int D = 5; // Down sampling factor
float T = 1.0; // Acquisition Time sec
double meanValue = 0.0;
double stdValue = 0.0;

int volatile sampleInd = 0; // Global Buffer Location
short int * volatile rawSignal; // Acquisition RAM Buffer
double * polySignal[D]; // PolySignal branches
double * polyIQ[2]; // Quadrature filtered, downsampled, demodulated signals
double * polyResult; // Reconstructed, LP filtered signal

// I-Q quadrature oscillations
const double I[D] = { 2.000000000000000, // Cosine
0.618033988749895,
-1.618033988749895,
-1.618033988749895,
0.618033988749894};
const double Q[D] = {0.000000000000000, // Sine
1.902113032590307,
1.175570504584947,
-1.175570504584946,
-1.902113032590307};


// AntiAliasing filter coefficients :: FIR window Kaiser, Fs=5000, Fc=300
const double AAF[15] = {0.017862400522538,
0.033885458153087,
0.050891294195008,
0.067512846793389,
0.082326310000912,
0.094008030100344,
0.101484759026756,
0.104057802415933,
0.101484759026756,
0.094008030100344,
0.082326310000912,
0.067512846793389,
0.050891294195008,
0.033885458153087,
0.017862400522538};
double * polyAAF[D]; // Polyphase downsampled impulse responses

// LP filter coefficients :: FIR window Kaiser, Fs=1000, Fc=15
const double LP[21] = { 0.041447420224253,
0.043208077329578,
0.044830173046221,
0.046298913638535,
0.047600786034868,
0.048723722606653,
0.049657248993218,
0.050392612896925,
0.050922892035903,
0.051243079731859,
0.051350146923975,
0.051243079731859,
0.050922892035903,
0.050392612896925,
0.049657248993218,
0.048723722606653,
0.047600786034868,
0.046298913638535,
0.044830173046221,
0.043208077329578,
0.041447420224253};

bool volatile BUSY_STATE = false; // Internal state

unsigned long int timemicros;


void computeOutput(){
timemicros = micros();
rawSignal[0] = rawSignal[5]; // First value adjust

short int offset = 0; // Offset
for(int h=0;h<Fs*T;h++)
offset+=rawSignal[h];
offset/=Fs*T;

for (int i=0;i<Fs*T/D;i++) // Initialize arrays
{
polyIQ[0][i] = 0;
polyIQ[1][i] = 0;
}

for (int j=0;j<D;j++)
{
// DownSampling
for (int i=j;i<Fs*T;i+=5)
polySignal[j][i/5] = (double)(rawSignal[i]-offset); // Downsampling and offset removal

for (int i=j;i<nelems(AAF);i+=5)
polyAAF[j][i/5] = AAF[i];

// AntiAlias Filtering
filter(polyAAF[j],nelems(AAF)/D,polySignal[j],(int) Fs*T/D);

// Quadrature Demodulation
for (int i=0;i<Fs*T/D;i++)
{
polyIQ[0][i] += I[j]*(polySignal[j][i]);
polyIQ[1][i] += Q[j]*(polySignal[j][i]);
}
}

// Norm calculation :: sqrt(I^2+Q^2)
for (int i=0;i<Fs*T/D;i++)
polyResult[i] = (double) sqrt(polyIQ[0][i]*polyIQ[0][i] + polyIQ[1][i]*polyIQ[1][i]);

// LP filtering
filter((double*) LP,nelems(LP),(double*) polyResult,(int) Fs*T/D);

// Elaborate stats
statistics();

double convFactor = 2.0*4.0/65535.0; // 2 * FullScale / (2^16-1)
meanValue *= convFactor;
stdValue  *= convFactor;

printResults();

polyFreeAlloc();
timemicros=micros()-timemicros;
Serial.println(timemicros);
}

bool polyAlloc()
{
if(NULL != rawSignal)
{
free(rawSignal); // Deallocate buffer memory
free(polyResult);
rawSignal = NULL;
polyResult= NULL;
}

rawSignal  = (short int *)malloc(Fs*T*sizeof(short int)); // Dynamic Memory Allocation
polyResult = (double *)malloc(Fs*T/D*sizeof(double));

polyIQ[0]  = (double *)malloc(Fs*T/D*sizeof(double));
polyIQ[1]  = (double *)malloc(Fs*T/D*sizeof(double));

bool polys = true;
for (int j=0;j<D;j++)
{
polySignal[j]=  (double *)malloc(Fs*T/D*sizeof(double));
polyAAF[j]   =  (double *)malloc(nelems(AAF)/D*sizeof(double));

polys &= polySignal[j] != NULL && polyAAF[j] != NULL;
}

return (rawSignal[0] != NULL && polyIQ[0] != NULL && polyIQ[1] != NULL && polyResult != NULL && polys);
}

void polyFreeAlloc()
{
for (int i=0;i<D;i++)
{
free(polySignal[i]);
polySignal[i] = NULL;
}

free(polyIQ[0]);
free(polyIQ[1]);
polyIQ[0] = NULL;
polyIQ[1] = NULL;
}

void filter(double *Num, int n, double *vect, int vLen)
{
double average = 0.0; // Initial conditions calculation
for(int h=0;h<vLen;h++)
average+=vect[h];
average/=(double)vLen;

double numbuf[n]; // Initialize FIFO FIR buffer
for(int h=0;h<n;h++)
numbuf[h]=average;

for (int h=0;h<vLen;h++){ // Filtering cycle
double FIR = 0.0;

for (int k=n-1;k>0;k--) // Cycle FIR buffer elements
numbuf[k]=numbuf[k-1];
numbuf[0] = vect[h]; // Push new element inside FIR buffer

for (int j=0;j<n;j++) // FIR convolution
FIR += numbuf[j]*Num[j];

vect[h] = FIR; // Output calculation
}
}

9  Products / Arduino Due / Re: ArduinoDUE - FloatingPointVS Integer math on: August 26, 2013, 04:21:08 pm
This is the integer math version:
Code:
#define nelems(x) sizeof(x)/sizeof(*x)

const int Fs = 5000; // Sample Rate
const int D = 5; // Down sampling factor
float T = 1.0; // Acquisition Time sec
double meanValue = 0.0;
double stdValue = 0.0;

int volatile sampleInd = 0; // Global Buffer Location
int * volatile rawSignal; // Acquisition RAM Buffer
int * polySignal[D]; // PolySignal branches
int * polyIQ[2]; // Quadrature filtered, downsampled, demodulated signals
unsigned int * polyResult; // Reconstructed, LP filtered signal

// I-Q quadrature oscillations
const float I[D] = {2.0, 0.61803398,-1.61803398,-1.61803398, 0.61803398};// Cosine
const float Q[D] = {0.0, 1.90211303, 1.17557050,-1.17557050,-1.90211303};// Sine


// AntiAliasing filter coefficients :: FIR window Kaiser, Fs=5000, Fc=300
const float AAF[15] = {0.01786240,0.03388546,0.05089129,0.06751284,0.08232631,0.09400803,0.10148476,0.10405780,0.10148476,0.09400803,0.08232631,0.06751284,0.05089129,0.03388546,0.01786240};
float * polyAAF[D]; // Polyphase downsampled impulse responses

// LP filter coefficients :: FIR window Kaiser, Fs=1000, Fc=15
const float LP[21] = {0.04144742,0.04320807,0.04483017,0.04629891,0.04760078,0.04872372,0.04965724,0.05039261,0.05092289,0.05124307,0.05135014,0.05124307,0.05092289,0.05039261,0.04965724,0.04872372,0.04760078,0.04629891,0.04483017,0.04320807,0.04144742};

void computeOutput(){
timemicros = micros();
rawSignal[0] = rawSignal[5]; // First value adjust

int offset = 0; // Offset
for(int h=0;h<Fs*T;h++)
offset+=rawSignal[h];
offset/=Fs*T;

for (int i=0;i<Fs*T/D;i++) // Initialize arrays
{
polyIQ[0][i] = 0;
polyIQ[1][i] = 0;
}

for (int j=0;j<D;j++)
{
// DownSampling
for (int i=j;i<Fs*T;i+=5)
polySignal[j][i/5] = rawSignal[i]-offset; // Downsampling and offset removal

for (int i=j;i<nelems(AAF);i+=5)
polyAAF[j][i/5] = AAF[i];

// AntiAlias Filtering
filter(polyAAF[j],nelems(AAF)/D,polySignal[j],(int) Fs*T/D);

// Quadrature Demodulation
for (int i=0;i<Fs*T/D;i++)
{
polyIQ[0][i] += I[j]*(polySignal[j][i]);
polyIQ[1][i] += Q[j]*(polySignal[j][i]);
}
}

// Norm calculation :: sqrt(I^2+Q^2)
for (int i=0;i<Fs*T/D;i++)
polyResult[i] = (unsigned int) sqrt(polyIQ[0][i]*polyIQ[0][i] + polyIQ[1][i]*polyIQ[1][i]);

// LP filtering
filter((float *) LP,nelems(LP),(int*) polyResult,(int) Fs*T/D);

// Elaborate stats
statistics();

double convFactor = 2.0*4.0/65535.0; // 2 * FullScale / (2^16-1)
meanValue *= convFactor;
stdValue  *= convFactor;

printResults();

polyFreeAlloc();
timemicros=micros()-timemicros;
Serial.println(timemicros);
}

bool polyAlloc()
{
if(NULL != rawSignal)
{
free(rawSignal); // Deallocate buffer memory
free(polyResult);
rawSignal = NULL;
polyResult= NULL;
}

rawSignal  = (int *)malloc(Fs*T*sizeof(int)); // Dynamic Memory Allocation
polyResult = (unsigned int *)malloc(Fs*T/D*sizeof(int));

polyIQ[0]  = (int *)malloc(Fs*T/D*sizeof(int));
polyIQ[1]  = (int *)malloc(Fs*T/D*sizeof(int));

bool polys = true;
for (int j=0;j<D;j++)
{
polySignal[j]=    (int *)malloc(Fs*T/D*sizeof(int));
polyAAF[j]   =  (float *)malloc(nelems(AAF)/D*sizeof(float));

polys &= polySignal[j] != NULL && polyAAF[j] != NULL;
}

return (rawSignal[0] != NULL && polyIQ[0] != NULL && polyIQ[1] != NULL && polyResult != NULL && polys);
}

void filter(float *Num, int n, int *vect, int vLen)
{
int average = 0; // Initial conditions calculation
for(int h=0;h<vLen;h++)
average+=vect[h];
average/=vLen;

int numbuf[n]; // Initialize FIFO FIR buffer
for(int h=0;h<n;h++)
numbuf[h]=average;

for (int h=0;h<vLen;h++){ // Filtering cycle
int FIR = 0;

for (int k=n-1;k>0;k--) // Cycle FIR buffer elements
numbuf[k]=numbuf[k-1];
numbuf[0] = vect[h]; // Push new element inside FIR buffer

for (int j=0;j<n;j++) // FIR convolution
FIR += (int) numbuf[j]*Num[j];

vect[h] = FIR; // Output calculation
}
}
10  Products / Arduino Due / Re: ArduinoDUE - FloatingPointVS Integer math on: August 26, 2013, 04:17:45 pm
Hi guys, thank for your replies. The code is quite long, so I'll try to post an extract for the two version in two different posts.
Before I post the code, I want to grant you that I get the same result in both ways. The algorythm has been first written in Matlab and then translated in C. To compare the results, I get the raw samples printed on Serial port, I copy and paste them in Matlab passing them through matlab algorythm. Except some normal fluctuations on the 4th decimal, the result it's the same.

Now,think about I've dinamically allocated some vectors using polyAlloc() function: rawSignal, polySignal, polyIQ and polyResult. I've also succesfully acquired 5000 16 bit samples and stored them inside rawSignal vector. Then I call computeOutput() function, that uses the filter() function.
11  Products / Arduino Due / ArduinoDUE - FloatingPointVS Integer math on: August 26, 2013, 10:42:58 am
Hi everybody,
I would like to ask you a simple question. Does anybody can explain me why floating point double precision math are almost 2x faster than integer math on ArduinoDUE?

I've implemented some digital signal processing on my arduino, like 5KS 16 bit sampling, quadrature demodulation, antialiasing filtering, downsampling, LP filtering, mean and standard deviation calculations. As I read on SAM3X8E manual, the uC has not a floating point unit, but it can emulate it. That's why many forums suggest to use integer math instead of float or double math, and that's the reason why the first implementation of the algorythm I did, used integer math.
But yesterday I was asking my self if I could get more precision using double math, even with some more computation time, and after some code upgrade, I got the final result:
  • more precision
  • half computation time

I'm wondered of the results I got and I just can not explain my self the reason why on an average of 11 algorythm executions, I get an average execution time of 714.18 [us] for integer math, against 355.28 [us] for double precision floating point math, i.e. 32bit native math VS 64bit emulated math.

I'm asking you this question, because this is part of my thesis work and I'm not able to justify this behavior, this is not the one expected.. Thanx
12  Products / Arduino Due / Re: Can't get Blink sketch (and others) to work on my Due on: August 22, 2013, 06:22:23 am
Hi guys, thanks for all your suggestions..
In my case, as for dinofizz, there was no way to make it work with any sketch. It seemed to be stuck, but all the voltages across board were fine and also compiling and flashing were ok.
After about 1 month following arduino support team trying to find the cause of the problem, they decided to change my board because no solution was found. I've sent the old board and received a new one with no extra fees.
I have to say the support team has been very professional and readly available.

I can only say you, without any certainty, that the problem seemed to happear after uploading a modified version of ArduinoISP, using SerialUSB instead of Serial instances.
I've also asked them to tell me the cause of the problem after debug, but I've still received no answer.
13  Products / Arduino Due / Re: Stop PWM signal on: August 08, 2013, 03:22:37 pm
Ok, thanks anyway... I would only know if it was a limit of mine in making it work, beacause inside the reference it's written you can..
14  Products / Arduino Due / Re: Stop PWM signal on: August 08, 2013, 02:38:43 pm
Don't you think that it's a problem not being able to change a pin mode once you use analogWrite to a pin?
So, the only way to change that pin functionality is to rewrite the firmware? It seems quite ridiculous..
15  Products / Arduino Due / Re: Stop PWM signal on: August 08, 2013, 01:01:00 pm
Hi Palliser, thank for your suggestion. Your workaround let me stop PWM, but then I'm not able to start it again.. This is an unpleasant behaviour, the only way I found to start and stop it, is to change the dutycycle. If someone has other idea, please let me know.
Is this problem due to arduinoDUE? Does anybody had in the past the need to start and stop PWM signal? I can't believe I'm the first... :-)
Pages: [1] 2