Dependencies:   DHT mbed

dsp_test.cpp

Committer:
elt14lpo
Date:
2017-05-12
Revision:
4:a89e836d9faf
Parent:
3:3f71950ceb71

File content as of revision 4:a89e836d9faf:

#include "mbed.h"
#include <iostream>     /*  cout */
#include <stdio.h>      /* printf */
#include <math.h>       /* sin */
#include <vector>
#include <stdlib.h>     /* abs */
#include <stdio.h>
#include <AnalogIn.h>
#include <stdint.h>
#include <DHT.h>
#include<sstream>
#include "luke_correlate_f32.h"
//using namespace std;

/* DEBUG FUNCTION
// ersätter Debug(xyz) med xyz , där xyz är din kod
//För att aktivera:
#define Debug(xyz) xyz

//För att "stänga av":
#define Debug(xyz)

//I din kod, skriv din debug kod liknande så här:
Debug( std::cout << "My text: " << myVariable << std::endl; );

*/

#define Debug(x) x
#define DebugPrintState(y) y
#define DebugArcSin(z) z


//----------VARIABLES HERE
const int dataLength = 1000;
const int captureLength = 50;
int dL = 1000;
int cL = 50;
double temp = 22;
double hum = 10;
double micDist = 0.250; //meters
double threshold_1 = 0; //value when going to active mode channel 1  //old hardcoded value = 330
double threshold_2 = 0; //value when going to active mode channel 2 //old hardcoded value = 200
double threshold_adjust = 15;  //used to adjust threshold, + for less sensitivity, - for increased sensitivity
bool calibratedStatus = false;      //flag to make sure Nuclueo only calibrated once for background noise
bool checkTemp = false;         //flag - true to checktemp, false to use predefined values
int positionOfMaxVal_1;
int positionOfMaxVal_2;
const double PI = 3.14159265358979323846;

// State machine
int    STATE;
//const int NONE     = -1;
const int IDLE  = 0;
const int CALIBRATE = 1;
const int TESTNEW = 2;
const int CALC  = 3;
const int CALC_ERROR = 4;
const int SEND   = 5;
//const int WAIT     = 9;

//dataLength behövs kanske inte, vector klassen kan växa med behov
float channel_1 [dataLength];
float channel_2 [dataLength];
int timestamps_1 [dataLength];
int timestamps_2 [dataLength];
float capture_1 [captureLength];
float *p1 = capture_1;
float capture_2 [captureLength];
float *p2 = capture_2;
float capturestamps_1 [captureLength];
float capturestamps_2 [captureLength];
float dsp_res [dataLength];
float *p_res = dsp_res;

int positiontest = 0;
int test = 9;
std::vector<double> delaytest(test);


AnalogIn mic1(A0);
AnalogIn mic2(A1);
AnalogIn mic3(A2);
DHT sensor(A3, DHT11);

//TIMER
Timer t;

//led can be used for status
DigitalOut led1(LED1);


//----------FUNCTIONS HERE
//Calculating distance between sound and camera
double calcDist(double t, double v)
{
    double s = t*v;
    return s;
}

//Calculating angle in radians, D distance between mic1 and mic2
double calcAng(double s, double D)
{
    return asin(s/D) + PI/2;
}

//Assuming the input value is temp as a number in degrees celcius and humidity as procent
double calcSoundSpeed(double temp, double hum)
{
    //Calculations were done in Matlab
    double speed = 331.1190 + 0.6016*temp + 0.0126*hum;
    return speed;
}

//translate angle to number for camera
string convertAngToCamNbr(double ang)
{
    ang = ang*(180 / PI) + 45;  //radianer till grader
    double angValues = 270;
    int stepValues = 50000;
    string tiltNumber = " 18000";   //hårdkodat Camera Pan värde

    double oneAng = stepValues/angValues;
    double cameraAngNumber = ang*oneAng;
    int panInt = (int)(cameraAngNumber);  //double to int
    //int to string
    string panNumber;
    ostringstream convert;
    convert << panInt;
    panNumber = convert.str();

    string send = panNumber + tiltNumber;
    return send;
}


//calc time delay by finding peak values in 2 vectors
//channel = 1 or 2
int FindPeak(int channel)
{
    float *channel_curr; //temporary vector with channel voltage values

    //if channel 1 then set current channel to channel 1
    if (channel == 1) {
        channel_curr = capture_1;
    } else channel_curr = capture_2;

    //reset max value & sum value
    double valueMax = 0;

    //reset array position
    int positionOfMaxVal = 0;

    //find largest value & mark that position in vectors
    for (int position = 0; position < captureLength; position++) {
        double val = abs(channel_curr[position]);
        if (val > valueMax ) {
            valueMax = val;
            positionOfMaxVal = position;
        }
    }
    return positionOfMaxVal;
}

double FindTimeDelay(int positionOfMaxVal_1, int positionOfMaxVal_2)
{
    double timemax_1 = capturestamps_1[positionOfMaxVal_1];
    double timemax_2 = capturestamps_2[positionOfMaxVal_2];
    double delay = timemax_1 - timemax_2;
    return delay; //if negative near microphone 1, if positive near micropnone 2
}


//get voltage value which represents audio amplitude from microphone
double getAudioValue(AnalogIn micX)
{
    return 1000*micX.read();
}


bool overThreshold(double micValue_1, double micValue_2)
{
    if ((micValue_1 > threshold_1) || (micValue_2 > threshold_2)) {
        return true;
    } else return false;
}

//true if voltage value in microphone is above the current threshold value
bool calibrateThreshold(double micValue, double currentThreshold)
{
    if ( micValue > currentThreshold ) {
        return true;
    } else return false;
}

void luke_correlate_f32(
  float* pSrcA,
  int srcALen,
  float* pSrcB,
  int srcBLen,
  float* pDst)
{


#ifndef ARM_MATH_CM0_FAMILY

  /* Run the below code for Cortex-M4 and Cortex-M3 */

  float *pIn1;                               /* inputA pointer */
  float *pIn2;                               /* inputB pointer */
  float *pOut = pDst;                        /* output pointer */
  float *px;                                 /* Intermediate inputA pointer */
  float *py;                                 /* Intermediate inputB pointer */
  float *pSrc1;                              /* Intermediate pointers */
  float sum, acc0, acc1, acc2, acc3;         /* Accumulators */
  float x0, x1, x2, x3, c0;                  /* temporary variables for holding input and coefficient values */
  int j, k = 0u, count, blkCnt, outBlockSize, blockSize1, blockSize2, blockSize3;  /* loop counters */
  int32_t inc = 1;                               /* Destination address modifier */


  /* The algorithm implementation is based on the lengths of the inputs. */
  /* srcB is always made to slide across srcA. */
  /* So srcBLen is always considered as shorter or equal to srcALen */
  /* But CORR(x, y) is reverse of CORR(y, x) */
  /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */
  /* and the destination pointer modifier, inc is set to -1 */
  /* If srcALen > srcBLen, zero pad has to be done to srcB to make the two inputs of same length */
  /* But to improve the performance,    
   * we assume zeroes in the output instead of zero padding either of the the inputs*/
  /* If srcALen > srcBLen,    
   * (srcALen - srcBLen) zeroes has to included in the starting of the output buffer */
  /* If srcALen < srcBLen,    
   * (srcALen - srcBLen) zeroes has to included in the ending of the output buffer */
  if(srcALen >= srcBLen)
  {
    /* Initialization of inputA pointer */
    pIn1 = pSrcA;

    /* Initialization of inputB pointer */
    pIn2 = pSrcB;

    /* Number of output samples is calculated */
    outBlockSize = (2u * srcALen) - 1u;

    /* When srcALen > srcBLen, zero padding has to be done to srcB    
     * to make their lengths equal.    
     * Instead, (outBlockSize - (srcALen + srcBLen - 1))    
     * number of output samples are made zero */
    j = outBlockSize - (srcALen + (srcBLen - 1u));

    /* Updating the pointer position to non zero value */
    pOut += j;

    //while(j > 0u)   
    //{   
    //  /* Zero is stored in the destination buffer */   
    //  *pOut++ = 0.0f;   

    //  /* Decrement the loop counter */   
    //  j--;   
    //}   

  }
  else
  {
    /* Initialization of inputA pointer */
    pIn1 = pSrcB;

    /* Initialization of inputB pointer */
    pIn2 = pSrcA;

    /* srcBLen is always considered as shorter or equal to srcALen */
    j = srcBLen;
    srcBLen = srcALen;
    srcALen = j;

    /* CORR(x, y) = Reverse order(CORR(y, x)) */
    /* Hence set the destination pointer to point to the last output sample */
    pOut = pDst + ((srcALen + srcBLen) - 2u);

    /* Destination address modifier is set to -1 */
    inc = -1;

  }

  /* The function is internally    
   * divided into three parts according to the number of multiplications that has to be    
   * taken place between inputA samples and inputB samples. In the first part of the    
   * algorithm, the multiplications increase by one for every iteration.    
   * In the second part of the algorithm, srcBLen number of multiplications are done.    
   * In the third part of the algorithm, the multiplications decrease by one    
   * for every iteration.*/
  /* The algorithm is implemented in three stages.    
   * The loop counters of each stage is initiated here. */
  blockSize1 = srcBLen - 1u;
  blockSize2 = srcALen - (srcBLen - 1u);
  blockSize3 = blockSize1;

  /* --------------------------    
   * Initializations of stage1    
   * -------------------------*/

  /* sum = x[0] * y[srcBlen - 1]    
   * sum = x[0] * y[srcBlen-2] + x[1] * y[srcBlen - 1]    
   * ....    
   * sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen - 1] * y[srcBLen - 1]    
   */

  /* In this stage the MAC operations are increased by 1 for every iteration.    
     The count variable holds the number of MAC operations performed */
  count = 1u;

  /* Working pointer of inputA */
  px = pIn1;

  /* Working pointer of inputB */
  pSrc1 = pIn2 + (srcBLen - 1u);
  py = pSrc1;

  /* ------------------------    
   * Stage1 process    
   * ----------------------*/

  /* The first stage starts here */
  while(blockSize1 > 0u)
  {
    /* Accumulator is made zero for every iteration */
    sum = 0.0f;

    /* Apply loop unrolling and compute 4 MACs simultaneously. */
    k = count >> 2u;

    /* First part of the processing with loop unrolling.  Compute 4 MACs at a time.    
     ** a second loop below computes MACs for the remaining 1 to 3 samples. */
    while(k > 0u)
    {
      /* x[0] * y[srcBLen - 4] */
      sum += *px++ * *py++;
      /* x[1] * y[srcBLen - 3] */
      sum += *px++ * *py++;
      /* x[2] * y[srcBLen - 2] */
      sum += *px++ * *py++;
      /* x[3] * y[srcBLen - 1] */
      sum += *px++ * *py++;

      /* Decrement the loop counter */
      k--;
    }

    /* If the count is not a multiple of 4, compute any remaining MACs here.    
     ** No loop unrolling is used. */
    k = count % 0x4u;

    while(k > 0u)
    {
      /* Perform the multiply-accumulate */
      /* x[0] * y[srcBLen - 1] */
      sum += *px++ * *py++;

      /* Decrement the loop counter */
      k--;
    }

    /* Store the result in the accumulator in the destination buffer. */
    *pOut = sum;
    /* Destination pointer is updated according to the address modifier, inc */
    pOut += inc;

    /* Update the inputA and inputB pointers for next MAC calculation */
    py = pSrc1 - count;
    px = pIn1;

    /* Increment the MAC count */
    count++;

    /* Decrement the loop counter */
    blockSize1--;
  }

  /* --------------------------    
   * Initializations of stage2    
   * ------------------------*/

  /* sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen-1] * y[srcBLen-1]    
   * sum = x[1] * y[0] + x[2] * y[1] +...+ x[srcBLen] * y[srcBLen-1]    
   * ....    
   * sum = x[srcALen-srcBLen-2] * y[0] + x[srcALen-srcBLen-1] * y[1] +...+ x[srcALen-1] * y[srcBLen-1]    
   */

  /* Working pointer of inputA */
  px = pIn1;

  /* Working pointer of inputB */
  py = pIn2;

  /* count is index by which the pointer pIn1 to be incremented */
  count = 0u;

  /* -------------------    
   * Stage2 process    
   * ------------------*/

  /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed.    
   * So, to loop unroll over blockSize2,    
   * srcBLen should be greater than or equal to 4, to loop unroll the srcBLen loop */
  if(srcBLen >= 4u)
  {
    /* Loop unroll over blockSize2, by 4 */
    blkCnt = blockSize2 >> 2u;

    while(blkCnt > 0u)
    {
      /* Set all accumulators to zero */
      acc0 = 0.0f;
      acc1 = 0.0f;
      acc2 = 0.0f;
      acc3 = 0.0f;

      /* read x[0], x[1], x[2] samples */
      x0 = *(px++);
      x1 = *(px++);
      x2 = *(px++);

      /* Apply loop unrolling and compute 4 MACs simultaneously. */
      k = srcBLen >> 2u;

      /* First part of the processing with loop unrolling.  Compute 4 MACs at a time.    
       ** a second loop below computes MACs for the remaining 1 to 3 samples. */
      do
      {
        /* Read y[0] sample */
        c0 = *(py++);

        /* Read x[3] sample */
        x3 = *(px++);

        /* Perform the multiply-accumulate */
        /* acc0 +=  x[0] * y[0] */
        acc0 += x0 * c0;
        /* acc1 +=  x[1] * y[0] */
        acc1 += x1 * c0;
        /* acc2 +=  x[2] * y[0] */
        acc2 += x2 * c0;
        /* acc3 +=  x[3] * y[0] */
        acc3 += x3 * c0;

        /* Read y[1] sample */
        c0 = *(py++);

        /* Read x[4] sample */
        x0 = *(px++);

        /* Perform the multiply-accumulate */
        /* acc0 +=  x[1] * y[1] */
        acc0 += x1 * c0;
        /* acc1 +=  x[2] * y[1] */
        acc1 += x2 * c0;
        /* acc2 +=  x[3] * y[1] */
        acc2 += x3 * c0;
        /* acc3 +=  x[4] * y[1] */
        acc3 += x0 * c0;

        /* Read y[2] sample */
        c0 = *(py++);

        /* Read x[5] sample */
        x1 = *(px++);

        /* Perform the multiply-accumulates */
        /* acc0 +=  x[2] * y[2] */
        acc0 += x2 * c0;
        /* acc1 +=  x[3] * y[2] */
        acc1 += x3 * c0;
        /* acc2 +=  x[4] * y[2] */
        acc2 += x0 * c0;
        /* acc3 +=  x[5] * y[2] */
        acc3 += x1 * c0;

        /* Read y[3] sample */
        c0 = *(py++);

        /* Read x[6] sample */
        x2 = *(px++);

        /* Perform the multiply-accumulates */
        /* acc0 +=  x[3] * y[3] */
        acc0 += x3 * c0;
        /* acc1 +=  x[4] * y[3] */
        acc1 += x0 * c0;
        /* acc2 +=  x[5] * y[3] */
        acc2 += x1 * c0;
        /* acc3 +=  x[6] * y[3] */
        acc3 += x2 * c0;


      } while(--k);

      /* If the srcBLen is not a multiple of 4, compute any remaining MACs here.    
       ** No loop unrolling is used. */
      k = srcBLen % 0x4u;

      while(k > 0u)
      {
        /* Read y[4] sample */
        c0 = *(py++);

        /* Read x[7] sample */
        x3 = *(px++);

        /* Perform the multiply-accumulates */
        /* acc0 +=  x[4] * y[4] */
        acc0 += x0 * c0;
        /* acc1 +=  x[5] * y[4] */
        acc1 += x1 * c0;
        /* acc2 +=  x[6] * y[4] */
        acc2 += x2 * c0;
        /* acc3 +=  x[7] * y[4] */
        acc3 += x3 * c0;

        /* Reuse the present samples for the next MAC */
        x0 = x1;
        x1 = x2;
        x2 = x3;

        /* Decrement the loop counter */
        k--;
      }

      /* Store the result in the accumulator in the destination buffer. */
      *pOut = acc0;
      /* Destination pointer is updated according to the address modifier, inc */
      pOut += inc;

      *pOut = acc1;
      pOut += inc;

      *pOut = acc2;
      pOut += inc;

      *pOut = acc3;
      pOut += inc;

      /* Increment the pointer pIn1 index, count by 4 */
      count += 4u;

      /* Update the inputA and inputB pointers for next MAC calculation */
      px = pIn1 + count;
      py = pIn2;

      /* Decrement the loop counter */
      blkCnt--;
    }

    /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here.    
     ** No loop unrolling is used. */
    blkCnt = blockSize2 % 0x4u;

    while(blkCnt > 0u)
    {
      /* Accumulator is made zero for every iteration */
      sum = 0.0f;

      /* Apply loop unrolling and compute 4 MACs simultaneously. */
      k = srcBLen >> 2u;

      /* First part of the processing with loop unrolling.  Compute 4 MACs at a time.    
       ** a second loop below computes MACs for the remaining 1 to 3 samples. */
      while(k > 0u)
      {
        /* Perform the multiply-accumulates */
        sum += *px++ * *py++;
        sum += *px++ * *py++;
        sum += *px++ * *py++;
        sum += *px++ * *py++;

        /* Decrement the loop counter */
        k--;
      }

      /* If the srcBLen is not a multiple of 4, compute any remaining MACs here.    
       ** No loop unrolling is used. */
      k = srcBLen % 0x4u;

      while(k > 0u)
      {
        /* Perform the multiply-accumulate */
        sum += *px++ * *py++;

        /* Decrement the loop counter */
        k--;
      }

      /* Store the result in the accumulator in the destination buffer. */
      *pOut = sum;
      /* Destination pointer is updated according to the address modifier, inc */
      pOut += inc;

      /* Increment the pointer pIn1 index, count by 1 */
      count++;

      /* Update the inputA and inputB pointers for next MAC calculation */
      px = pIn1 + count;
      py = pIn2;

      /* Decrement the loop counter */
      blkCnt--;
    }
  }
  else
  {
    /* If the srcBLen is not a multiple of 4,    
     * the blockSize2 loop cannot be unrolled by 4 */
    blkCnt = blockSize2;

    while(blkCnt > 0u)
    {
      /* Accumulator is made zero for every iteration */
      sum = 0.0f;

      /* Loop over srcBLen */
      k = srcBLen;

      while(k > 0u)
      {
        /* Perform the multiply-accumulate */
        sum += *px++ * *py++;

        /* Decrement the loop counter */
        k--;
      }

      /* Store the result in the accumulator in the destination buffer. */
      *pOut = sum;
      /* Destination pointer is updated according to the address modifier, inc */
      pOut += inc;

      /* Increment the pointer pIn1 index, count by 1 */
      count++;

      /* Update the inputA and inputB pointers for next MAC calculation */
      px = pIn1 + count;
      py = pIn2;

      /* Decrement the loop counter */
      blkCnt--;
    }
  }

  /* --------------------------    
   * Initializations of stage3    
   * -------------------------*/

  /* sum += x[srcALen-srcBLen+1] * y[0] + x[srcALen-srcBLen+2] * y[1] +...+ x[srcALen-1] * y[srcBLen-1]    
   * sum += x[srcALen-srcBLen+2] * y[0] + x[srcALen-srcBLen+3] * y[1] +...+ x[srcALen-1] * y[srcBLen-1]    
   * ....    
   * sum +=  x[srcALen-2] * y[0] + x[srcALen-1] * y[1]    
   * sum +=  x[srcALen-1] * y[0]    
   */

  /* In this stage the MAC operations are decreased by 1 for every iteration.    
     The count variable holds the number of MAC operations performed */
  count = srcBLen - 1u;

  /* Working pointer of inputA */
  pSrc1 = pIn1 + (srcALen - (srcBLen - 1u));
  px = pSrc1;

  /* Working pointer of inputB */
  py = pIn2;

  /* -------------------    
   * Stage3 process    
   * ------------------*/

  while(blockSize3 > 0u)
  {
    /* Accumulator is made zero for every iteration */
    sum = 0.0f;

    /* Apply loop unrolling and compute 4 MACs simultaneously. */
    k = count >> 2u;

    /* First part of the processing with loop unrolling.  Compute 4 MACs at a time.    
     ** a second loop below computes MACs for the remaining 1 to 3 samples. */
    while(k > 0u)
    {
      /* Perform the multiply-accumulates */
      /* sum += x[srcALen - srcBLen + 4] * y[3] */
      sum += *px++ * *py++;
      /* sum += x[srcALen - srcBLen + 3] * y[2] */
      sum += *px++ * *py++;
      /* sum += x[srcALen - srcBLen + 2] * y[1] */
      sum += *px++ * *py++;
      /* sum += x[srcALen - srcBLen + 1] * y[0] */
      sum += *px++ * *py++;

      /* Decrement the loop counter */
      k--;
    }

    /* If the count is not a multiple of 4, compute any remaining MACs here.    
     ** No loop unrolling is used. */
    k = count % 0x4u;

    while(k > 0u)
    {
      /* Perform the multiply-accumulates */
      sum += *px++ * *py++;

      /* Decrement the loop counter */
      k--;
    }

    /* Store the result in the accumulator in the destination buffer. */
    *pOut = sum;
    /* Destination pointer is updated according to the address modifier, inc */
    pOut += inc;

    /* Update the inputA and inputB pointers for next MAC calculation */
    px = ++pSrc1;
    py = pIn2;

    /* Decrement the MAC count */
    count--;

    /* Decrement the loop counter */
    blockSize3--;
  }

#else

  /* Run the below code for Cortex-M0 */

  float *pIn1 = pSrcA;                       /* inputA pointer */
  float *pIn2 = pSrcB + (srcBLen - 1u);      /* inputB pointer */
  float sum;                                 /* Accumulator */
  int i = 0u, j;                            /* loop counters */
  int inv = 0u;                             /* Reverse order flag */
  int tot = 0u;                             /* Length */

  /* The algorithm implementation is based on the lengths of the inputs. */
  /* srcB is always made to slide across srcA. */
  /* So srcBLen is always considered as shorter or equal to srcALen */
  /* But CORR(x, y) is reverse of CORR(y, x) */
  /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */
  /* and a varaible, inv is set to 1 */
  /* If lengths are not equal then zero pad has to be done to  make the two    
   * inputs of same length. But to improve the performance, we assume zeroes    
   * in the output instead of zero padding either of the the inputs*/
  /* If srcALen > srcBLen, (srcALen - srcBLen) zeroes has to included in the    
   * starting of the output buffer */
  /* If srcALen < srcBLen, (srcALen - srcBLen) zeroes has to included in the   
   * ending of the output buffer */
  /* Once the zero padding is done the remaining of the output is calcualted   
   * using convolution but with the shorter signal time shifted. */

  /* Calculate the length of the remaining sequence */
  tot = ((srcALen + srcBLen) - 2u);

  if(srcALen > srcBLen)
  {
    /* Calculating the number of zeros to be padded to the output */
    j = srcALen - srcBLen;

    /* Initialise the pointer after zero padding */
    pDst += j;
  }

  else if(srcALen < srcBLen)
  {
    /* Initialization to inputB pointer */
    pIn1 = pSrcB;

    /* Initialization to the end of inputA pointer */
    pIn2 = pSrcA + (srcALen - 1u);

    /* Initialisation of the pointer after zero padding */
    pDst = pDst + tot;

    /* Swapping the lengths */
    j = srcALen;
    srcALen = srcBLen;
    srcBLen = j;

    /* Setting the reverse flag */
    inv = 1;

  }

  /* Loop to calculate convolution for output length number of times */
  for (i = 0u; i <= tot; i++)
  {
    /* Initialize sum with zero to carry on MAC operations */
    sum = 0.0f;

    /* Loop to perform MAC operations according to convolution equation */
    for (j = 0u; j <= i; j++)
    {
      /* Check the array limitations */
      if((((i - j) < srcBLen) && (j < srcALen)))
      {
        /* z[i] += x[i-j] * y[j] */
        sum += pIn1[j] * pIn2[-((int32_t) i - j)];
      }
    }
    /* Store the output in the destination buffer */
    if(inv == 1)
      *pDst-- = sum;
    else
      *pDst++ = sum;
  }

#endif /*   #ifndef ARM_MATH_CM0_FAMILY */

}

/**    
 * @} end of Corr group    
 */

// main() runs in its own thread in the OS
int main()
{
   
    for(int i = 0; i < test; i++) {
        delaytest[i] = -420 + i*105;
    }
    t.start(); // start timer

    //while (true) {
    led1 = !led1;
    wait(0.5);


    //STATE MACHINE
    STATE = IDLE;
    //int counter = 0;
    while (true) {
        switch (STATE) {
            case IDLE: //always start here
                DebugPrintState( std::cout << "Nucleo state is IDLE: " << std::endl; );
                Debug( wait(0.5); );
                if (!calibratedStatus)  STATE = CALIBRATE;
                else STATE = TESTNEW;
                break;

            case CALIBRATE:
                DebugPrintState( std::cout << "Nucleo state is CALIBRATE: " << std::endl; );
                Debug( wait(1); );
                //listen for X seconds to background noise, to set accurate threshold value
                // This should be done only once when rebooting Nucleo
                int startTime = t.read_us();
                int offsetTime = 3000; //microseconds
                int blinkTime = 500; //microseconds
                while (t.read_us() < (startTime + offsetTime) ) {
                    double micValue_1 = getAudioValue(mic1);
                    if ( calibrateThreshold(micValue_1, threshold_1) ) {
                        threshold_1 = micValue_1;       //threshold value updated
                    }
                    double micValue_2 = getAudioValue(mic2);
                    if ( calibrateThreshold(micValue_2, threshold_2) ) {
                        threshold_2 = micValue_2;       //threshold value updated
                    }
                    //make LED blink every 500 ms
                    if ( t.read_us() > (startTime + blinkTime) ) {
                        led1 = !led1;
                        blinkTime = blinkTime + 500;
                    }
                }
                threshold_1 = threshold_2 + threshold_adjust;
                threshold_2 = threshold_2 + threshold_adjust;

                //Calibrate temp and hum
                if(checkTemp){
                    bool done = false;
                    while(!done) {
                        if(sensor.readData() == 0) {
                            temp = sensor.ReadTemperature(CELCIUS);
                            hum = sensor.ReadHumidity();
                            DebugPrintState(std::cout << "Temp: " << temp << "Degrees Celcius" <<std::endl; );
                            DebugPrintState(std::cout << "Hum: " << temp << "%" <<std::endl; );
                            done = true;
                        }
                    }
                }

                calibratedStatus = true;
                STATE = TESTNEW; //next state
                break;

            case TESTNEW:
                DebugPrintState( std::cout << "Nucleo state is TESTNEW: " << std::endl; );
                int i = 0;
                bool quit = false;
                while(!quit) {
                    channel_1[i] = getAudioValue(mic1);
                    timestamps_1[i] = t.read_us();
                    channel_2[i] = getAudioValue(mic2);
                    timestamps_2[i] = t.read_us();
                    if(overThreshold(channel_1[i], channel_2[i]) == true) {
                        capture_1[0] = channel_1[i];
                        capturestamps_1[0] = timestamps_1[i];
                        capture_2[0] = channel_2[i];
                        capturestamps_2[0] = timestamps_2[i];
                        for(int i = 1; i < captureLength; i++) {
                            capture_1[i] = getAudioValue(mic1);
                            capturestamps_1[i] = t.read_us();
                            capture_2[i] = getAudioValue(mic2);
                            capturestamps_2[i] = t.read_us();
                        }
                        quit = true;
                    }
                    if(i < dataLength) {
                        i++;
                    } else {
                        i = 0;
                    }
                }
                STATE = CALC;
                break;

           
            case CALC:
                DebugPrintState( std::cout << "Nucleo state is CALC: " << std::endl; );
                //Debug( wait(0.5); );
                luke_correlate_f32(p1, cL, p2, cL, p_res);
                Debug(
                for(int i = 0; i < dataLength; i++){
                    std::cout << dsp_res[i] << " ";
                });
                
                int positionOfMaxVal_1 = FindPeak(1);
                int positionOfMaxVal_2 = FindPeak(2);
                //run functions
                double timedelay = FindTimeDelay(positionOfMaxVal_1, positionOfMaxVal_2); //microseceonds
                if(abs(timedelay) > micDist/calcSoundSpeed(temp, hum)){
                    STATE = CALC_ERROR;
                    break;
                }
                double speed = calcSoundSpeed(temp, hum); //meters per second
                double distance = calcDist(timedelay/1000000, speed); //input converted to meters
                double angle = calcAng((double)distance, micDist); //0,15m = 15cm = 150mm, double type cast because of asin function in angle calculation
                //go to state SEND if no calc_error

                Debug(
                    std::cout << "max position for channel 1: " << positionOfMaxVal_1+1 << std::endl;
                    std::cout << "max position for channel 2: " << positionOfMaxVal_2+1 << std::endl;
                    std::cout << "run FindPeak, delay is: " << timedelay << "microseconds" << std::endl;
                    std::cout << "run calcDist, delta s is: " << distance << "  millimeters" << std::endl;
                    std::cout << "run calcAngle, angle is: " << angle << " radians" << std::endl;
                    std::cout << "run calcAngle, angle is: " << angle*(180 / PI) << " degrees" << std::endl;
                    std::cout << "run convertAngToCamNbr, coordinates: "<< convertAngToCamNbr(angle)<<std::endl; //return "panNumber tiltNumber";
                );
                if (angle > (3 * PI )/2 || angle < 0 ) {       //vinkel larger than 270 eller minde än noll
                    STATE = CALC_ERROR;
                } else {
                    STATE = SEND;
                }
                break;

            case CALC_ERROR:
                DebugPrintState( std::cout << "Nucleo state is CALC_ERROR: " << std::endl; );
                Debug( wait(0.5); );
                //error message
                std::cout << "Error. angle not within limits 0 -270 degrees" << std::endl;
                //nollställ vektorer, , stoppa klockan , osv
                STATE = TESTNEW;
                break;

            case SEND:
                DebugPrintState( std::cout << "Nucleo state is SEND: " << std::endl; );
                Debug( wait(0.5); );
                // send coordinates to serial port to camera
                std::cout<<convertAngToCamNbr(angle)<<std::endl; //return "panNumber tiltNumber";
                Debug( wait(0.5); );
                STATE = IDLE;
                wait(5);
                break;
        }
    }
}