Error in loop

So i’ve this error/loop. I’m (trying) to listen to a function generator that gives a sine wave, and trying to put all the analog in input into an array. (The DFT will come later) But I disabled the function generator and my console is still stuck in the loop… The output in the console is:

nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
nee
381
ja
376
ja
380
ja
376
ja
380
ja
376
(And this goes on and on and on. "Nee" won't be there anymore)

And the code itself is:

#include <TimerOne.h>
#define arraymax 40

int voltage[arraymax];
int dftflag = 0;
int readcounter = 0;

void setup() {
  Serial.begin(9600);
  Timer1.initialize(250); // timer for 250us = 4000Hz
  Timer1.attachInterrupt( readinputIsr ); // attach the function to the interrupt routine
}

void loop() 
{
  if(dftflag == 1)
  {
	  for(int i = 0; i < arraymax; i++)
	  {
		  Serial.println(voltage[i]);
                  Serial.println("ja");
	  }
  }
}

void readinputIsr()
{
	if(dftflag == 0)
	{
		// Read the input data
		voltage[readcounter] = analogRead(A3);
                 Serial.println("nee");
		readcounter++;
		if(readcounter > arraymax)
		{
			readcounter = 0;
			dftflag = 1;
		}
	}
}

Does anyone have any ideas?

you never set your dftflag back to zero so you write out the existing result every time you go around loop();

Dr_Ugi: you never set your dftflag back to zero so you write out the existing result every time you go around loop();

"nee" is printed in the ISR, which is a mistake. Serial output does not belong in an ISR.

But I disabled the function generator and my console is still stuck in the loop.

So what? The ISR is triggered by a timer, not the function generator (whatever that is). All variables used in an ISR AND in other code need to be declared volatile.

Along with those things,

Variable readcounter doesn't appear to be managed properly in the ISR. The test is whether it's greater than the constant arraymax, after it's been incremented. If it's greater, then its previous value was equal to arraymax, and the sketch tried to store something at voltage[arraymax]. But, as an index, arraymax is beyond the bounds of the array voltage[], which runs from voltage[0] to voltage [arraymax-1]. I think that the test should be for either ==, or >=. Otherwise, a couple of memory locations are improperly overwritten.

The original post references the DFT. The DFT implicilty assumes that all of the samples are taken at equal time intervals. This technique, using analogRead, will have jitter due to variation in interrupt latency due to other interrupts - like the USART or Timer0 - firing ahead of the Timer1 interrupt. You might want to consider looking at the ADC chapter in the datasheet, and learning how to let a Timer1 event autotrigger the ADC. In that fashion, the ADC timing depends only on the hardware, and isn't affected by anything that goes on in the program as long as it gets read before the next conversion completes. If you properly manage the Timer1 overflow flag in the ADC ISR, there's no real necessity for Timer1 to ever actually throw an interrupt.

Allright, I’ve looked into the code and fixed it untill the last few pieces of code.
But there is still something wrong with it, but I can’t find is really…

This is what is supposed to be happening:

  1. There is a sine wave on the analog input.
  2. The signal is processed with DFT
  3. When the signal is more than 1kHz, the led will go on.

This is what is happening:

  1. There is a sine wave on the analog input (doesn’t matter on which frequency)
  2. On the serial output there are just random numbers (but an higher freq are equal with greater numbers)
  3. The LED will sometimes will turn on and off random.

What am I doing wrong?

#include <TimerOne.h>
#define arraymax 40
#define PI2 6.2832

int led = 13;
int ledpositief = 0; 
int n, k;  
volatile int dftflag = 0;
volatile int readcounter = 0;
int voltage[arraymax]; // discrete-time signal, x
float Xre[arraymax], Xim[arraymax]; // DFT of x (real and imaginary parts)
float P[arraymax];           // power spectrum of x

void setup() {
  Serial.begin(9600);
  Timer1.initialize(250); // timer for 250us = 4000Hz
  Timer1.attachInterrupt( readinputIsr ); // attach the function to the interrupt routine
  pinMode(led, OUTPUT);    
}

void loop() 
{
  if(dftflag == 1)
  {
  for(int i = 0; i < arraymax; i++)
  {
 DFT();
  }
  dftflag = 0;
  }
  
  for(int i = 0; i < arraymax; i++)
  {
 if( i >= 4 && P[i] > 50)  // Hier wordt gecontroleerd of in een frequentieband boven de 1000 hz een waarde is gezien (dus dat de frequentie aanwezig is)
 {
 ledpositief = 1;
 }
 else
 {
 ledpositief = 0;
 }
  }
  
  if(ledpositief == 1)
  {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  }
  else
  {
    digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  }
}

void readinputIsr()
{
 if(dftflag == 0)
 {
 // Read the input data
 voltage[readcounter] = analogRead(A3);
 readcounter++;
 if(readcounter >= arraymax)
 {
 readcounter = 0;
 dftflag = 1;
 }
 }
}

void DFT()
{
    
  for (k=0 ; k<arraymax ; ++k)
    {
        // Real part of X[k]
        Xre[k] = 0;
        for (n=0 ; n<arraymax ; ++n) Xre[k] += voltage[n] * cos(n * k * PI2 / arraymax);
         
        // Imaginary part of X[k]
        Xim[k] = 0;
        for (n=0 ; n<arraymax ; ++n) Xim[k] -= voltage[n] * sin(n * k * PI2 / arraymax);
         
        // Power at kth frequency bin
        P[k] = Xre[k]*Xre[k] + Xim[k]*Xim[k];
 Serial.println(P[k]);
    }
    

}

The sketch calls DFT() 40 times when it completes a sample period. I think that you intended to call it once.

After fixing that, I'd recommend is printing the array of samples, to see if it's what you expected.

Also, tell us about the analog signal - what's the source, what's its magnitude, what's its DC level, and how is it coupled to the analog input? And, show us some output - particularly the voltage array, both X arrays, and the output array P. "I see random numbers" doesn't give us much to work with.