I am pretty new to the photon 2 and I was trying to calculate FFT using photon based on this description Appendix B: https://paulbourke.net/miscellaneous/dft/
However, during my test code, my photon 2 is keep getting offline, I am not sure if there is anything wrong in my code to make this happen, can anyone help me check this issue?
Many thanks to all the help and advice.
I am not sure how to post the code well and easy to read so I just copy paste what I have:
#include "Particle.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
/*
This computes an in-place complex-to-complex FFT
x and y are the real and imaginary arrays of 2^m points.
dir = 1 gives forward transform
dir = -1 gives reverse transform
*/
void FFT(short int dir, int m, float* x, float* y)
{
int n, i, i1, j, k, i2, l, l1, l2;
float c1, c2, tx, ty, t1, t2, u1, u2, z;
/* Calculate the number of points */
n = 1;
for (i = 0; i < m; i++)
n *= 2;
/* Do the bit reversal */
i2 = n >> 1;
j = 0;
for (i = 0; i < n - 1; i++) {
if (i < j) {
tx = x[i];
ty = y[i];
x[i] = x[j];
y[i] = y[j];
x[j] = tx;
y[j] = ty;
}
k = i2;
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
}
/* Compute the FFT */
c1 = -1.0;
c2 = 0.0;
l2 = 1;
for (l = 0; l < m; l++) {
l1 = l2;
l2 <<= 1;
u1 = 1.0;
u2 = 0.0;
for (j = 0; j < l1; j++) {
for (i = j; i < n; i += l2) {
i1 = i + l1;
t1 = u1 * x[i1] - u2 * y[i1];
t2 = u1 * y[i1] + u2 * x[i1];
x[i1] = x[i] - t1;
y[i1] = y[i] - t2;
x[i] += t1;
y[i] += t2;
}
z = u1 * c1 - u2 * c2;
u2 = u1 * c2 + u2 * c1;
u1 = z;
}
c2 = sqrt((1.0 - c1) / 2.0);
if (dir == 1)
c2 = -c2;
c1 = sqrt((1.0 + c1) / 2.0);
}
/* Scaling for forward transform */
if (dir == 1) {
for (i = 0; i < n; i++) {
x[i] /= n;
y[i] /= n;
}
}
return;
}
void setup() {
// Setup Serial and connect to cloud
Particle.connect();
Serial.begin(9600);
}
//Checks if Particle is connected to cloud before publishing
void pubHook(String str){
int currentMillis = millis();
while(millis() - currentMillis <= 60000){
if(Particle.connected() == FALSE){
Serial.printlnf("Particle is Reconnecting");
Particle.connect();
delay(1000);
}
else{
Serial.printlnf("Particle is connected");
Particle.publish("Webhook", str, PRIVATE);
delay(500);
return;
}
}
Serial.printlnf("TIMEOUT: Cannot connect to internet");
return;
}
void loop() {
short int dir = 1;
int m = 10;
const int N = 64;
float x[N]; // x is real part, y is imag part
float y[N];
for (int i = 0; i < N; i++) {
x[i] = sin(8.0 * i * 0.01745); // construct a dataset which main F = 4;
y[i] = 0.0;
}
pubHook("1"); // for debug
FFT(dir, m, (float*)x, (float*)y);
pubHook("2"); // for debug
for (int j = 0; j < N; j++) { // calculate the magnitude and frequency
x[j] = sqrt(x[j] * x[j] + y[j] * y[j]);
y[j] = j * 360.0 / N;
}
for (int i = 0; i < 5; i++)
Serial.printlnf("%10.15lf, %10.15lf \n", x[i], y[i]); // print something to check
}
It's not entirely obvious to me what is causing the disconnection, however you have a different problem.
You call pubHook twice per loop, and when cloud connected it will publish and wait 500 milliseconds. This will far exceed the publish rate limitation. For debugging you should use serial debugging instead of publishing.
Also you may want to insert:
SYSTEM_THREAD(ENABLED);
near the top, not in a function. That will allow the cloud connection to be serviced while you are busy doing other things. If you don't do that and block the loop for very long, you will lose the cloud connection.
Thanks for the advice! I changed the code based on what you suggested:
But this time when I was trying to flash the code into photon 2, the device cannot even connect. The green light shined once then dimmed, and no other light is shining anymore. Then I got a warning said the USD device is not recognized. I tried reconnect but nothing works. What makes this happen? BTW I am using the web IDE to flash the code, not sure if this matters.
#include "Particle.h"
SYSTEM_THREAD(ENABLED);
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
/*
This computes an in-place complex-to-complex FFT
x and y are the real and imaginary arrays of 2^m points.
dir = 1 gives forward transform
dir = -1 gives reverse transform
*/
void FFT(short int dir, int m, float* x, float* y)
{
int n, i, i1, j, k, i2, l, l1, l2;
float c1, c2, tx, ty, t1, t2, u1, u2, z;
/* Calculate the number of points */
n = 1;
for (i = 0; i < m; i++)
n *= 2;
/* Do the bit reversal */
i2 = n >> 1;
j = 0;
for (i = 0; i < n - 1; i++) {
if (i < j) {
tx = x[i];
ty = y[i];
x[i] = x[j];
y[i] = y[j];
x[j] = tx;
y[j] = ty;
}
k = i2;
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
}
/* Compute the FFT */
c1 = -1.0;
c2 = 0.0;
l2 = 1;
for (l = 0; l < m; l++) {
l1 = l2;
l2 <<= 1;
u1 = 1.0;
u2 = 0.0;
for (j = 0; j < l1; j++) {
for (i = j; i < n; i += l2) {
i1 = i + l1;
t1 = u1 * x[i1] - u2 * y[i1];
t2 = u1 * y[i1] + u2 * x[i1];
x[i1] = x[i] - t1;
y[i1] = y[i] - t2;
x[i] += t1;
y[i] += t2;
}
z = u1 * c1 - u2 * c2;
u2 = u1 * c2 + u2 * c1;
u1 = z;
}
c2 = sqrt((1.0 - c1) / 2.0);
if (dir == 1)
c2 = -c2;
c1 = sqrt((1.0 + c1) / 2.0);
}
/* Scaling for forward transform */
if (dir == 1) {
for (i = 0; i < n; i++) {
x[i] /= n;
y[i] /= n;
}
}
return;
}
void pubHook(String str){
int currentMillis = millis();
while(millis() - currentMillis <= 60000){
if(Particle.connected() == FALSE){
Serial.printlnf("Particle is Reconnecting");
Particle.connect();
delay(1000);
}
else{
Serial.printlnf("Particle is connected");
Particle.publish("Webhook", str, PRIVATE);
delay(500);
return;
}
}
Serial.printlnf("TIMEOUT: Cannot connect to internet");
return;
}
void setup() {
// Setup Serial and connect to cloud
Particle.connect();
Serial.begin(9600);
}
void loop() {
short int dir = 1;
int m = 10;
const int N = 32;
float x[N]; // x is real part, y is imag part
float y[N];
for (int i = 0; i < N; i++) {
x[i] = sin(8.0 * i * 0.01745); // construct a dataset which main F = 4;
y[i] = 0.0;
}
Serial.printlnf("start");
FFT(dir, m, (float*)x, (float*)y);
Serial.printlnf("end");
for (int j = 0; j < N; j++) { // calculate the magnitude and frequency
x[j] = sqrt(x[j] * x[j] + y[j] * y[j]);
y[j] = j * 360.0 / N;
}
for (int i = 0; i < 5; i++)
Serial.printlnf("%10.15lf, %10.15lf \n", x[i], y[i]); // will give ascending indices from the str
}
I pull out the USB cable and reconnect, then the PC recognize the photon 2, I can flash the example code "flashing LED" into photon 2 without any problem. But when I flash the code I pasted here, the problem showed up again.
The green light shined once then no light is shining anymore. Then USB cannot recognize the device.
I did the whole process several times, but each time the example code "flashing LED" and other toy code works, not the one I pasted here.
Could that be the problem with Photon 2? I have Photon 1 and Argon at my hand, do you think I should try these two?
Thanks,
Nianyu Jiang
Hi @bko ,
Thank you for carefully went through the code and this solved the problem! I did not expect this will cause the USB device unrecognize though.
Could this cause any of the error such as Memory Manager fault?
Yes, overwriting memory can have bad side effects like that. The MCU runs in a single memory and privilege space, so corrupting memory can affect Device OS or the Realtek SDK.