Array values set to 'ovf' after memset

I am testing a library i wrote that allows for easy frequency analysis. In my test program, i generate a crude rect signal that is saved as a 128 value float array. When I look at the output (the println seen in the code below), i get some values showing up as -0 or ovf. These can not be set. It works without the library (everything that has anything to do with the FrequencyAnalyzer commented out), but the compiler can’t just override already assigned memory, can it?

Test program:

#include "FundamentalFrequencyAnalyzer.h";


void setup() {
  Serial.begin(115200);
  FundamentalFrequencyAnalyzer ffa = FundamentalFrequencyAnalyzer();
  float samples[128] = {};
  memset(samples, 0, 128);
  for(int i = 0; i < 128; i++){
    Serial.println(samples[i]);
  }
  boolean b = 0;
  uint8_t j = 0;
  for (int i = 0; i < 128; i++) {
    samples[i] = b;
    if (j >= 16) {
      b ^= 1;
      j = 0;
    }
    j++;
  }
  ffa.get128(samples, 1000);
}

void loop() {

}

Header:

#ifndef FundamentalFrequencyAnalyzer_h
#define FundamentalFrequencyAnalyzer_h

#include "Arduino.h"

#define WIN_TYP_RECTANGLE FFT_WIN_TYP_RECTANGLE
#define WIN_TYP_HAMMING FFT_WIN_TYP_HAMMING
#define WIN_TYP_HANN FFT_WIN_TYP_HANN
#define WIN_TYP_TRIANGLE FFT_WIN_TYP_TRIANGLE
#define WIN_TYP_NUTTALL FFT_WIN_TYP_NUTTALL
#define WIN_TYP_BLACKMAN FFT_WIN_TYP_NUTTALL
#define WIN_TYP_BLACKMAN_NUTTALL FFT_WIN_TYP_BLACKMAN_NUTTALL
#define WIN_TYP_BLACKMAN_HARRIS FFT_WIN_TYP_BLACKMAN_HARRIS
#define WIN_TYP_FLT_TOP FFT_WIN_TYP_FLT_TOP
#define WIN_TYP_WELCH FFT_WIN_TYP_WELCH

class FundamentalFrequencyAnalyzer {
  public:
    FundamentalFrequencyAnalyzer(uint8_t windowType);
    FundamentalFrequencyAnalyzer();
    uint16_t get32(float *samples, uint16_t samplingFrequency);
    uint16_t get64(float *samples, uint16_t samplingFrequency);
    uint16_t get128(float *samples, uint16_t samplingFrequency);
    uint16_t get256(float *samples, uint16_t samplingFrequency);
  private:
    uint8_t _windowType;
    float _vReal32[32];
    float _vImag32[32];
    float _vReal64[64];
    float _vImag64[64];
    float _vReal128[128];
    float _vImag128[128];
    float _vReal256[256];
    float _vImag256[256];
};

#endif

Source:

#include "Arduino.h"
#include "src\arduinoFFT.h"
#include "FundamentalFrequencyAnalyzer.h"

FundamentalFrequencyAnalyzer::FundamentalFrequencyAnalyzer(uint8_t windowType)
{
  _windowType = windowType;
}

FundamentalFrequencyAnalyzer::FundamentalFrequencyAnalyzer()
{
  _windowType = WIN_TYP_RECTANGLE;
}

uint16_t FundamentalFrequencyAnalyzer::get32(float *samples, uint16_t samplingFrequency)
{
  memcpy(_vReal32, samples, 32);
  memset(_vImag32, 0, 32);
  arduinoFFT FFT = arduinoFFT(_vReal32, _vImag32, 32, samplingFrequency); // create FFT object
  FFT.DCRemoval();
  FFT.Windowing(_windowType, FFT_FORWARD);
  FFT.Compute(FFT_FORWARD);
  FFT.ComplexToMagnitude();
  return (uint16_t)FFT.MajorPeak();
}

uint16_t FundamentalFrequencyAnalyzer::get64(float *samples, uint16_t samplingFrequency)
{
  memcpy(_vReal64, samples, 64);
  memset(_vImag64, 0, 64);
  arduinoFFT FFT = arduinoFFT(_vReal64, _vImag64, 64, samplingFrequency); // create FFT object
  FFT.DCRemoval();
  FFT.Windowing(_windowType, FFT_FORWARD);
  FFT.Compute(FFT_FORWARD);
  FFT.ComplexToMagnitude();
  return (uint16_t)FFT.MajorPeak();
}

uint16_t FundamentalFrequencyAnalyzer::get128(float *samples, uint16_t samplingFrequency)
{
  memcpy(_vReal128, samples, 128);
  memset(_vImag128, 0, 128);
  
  arduinoFFT FFT = arduinoFFT(_vReal128, _vImag128, 128, samplingFrequency); // create FFT object
  FFT.DCRemoval();
  FFT.Windowing(_windowType, FFT_FORWARD);
  FFT.Compute(FFT_FORWARD);
  FFT.ComplexToMagnitude();
  
  return (uint16_t)FFT.MajorPeak();
}

uint16_t FundamentalFrequencyAnalyzer::get256(float *samples, uint16_t samplingFrequency)
{
  memcpy(_vReal256, samples, 256);
  memset(_vImag256, 0, 256);
  arduinoFFT FFT = arduinoFFT(_vReal256, _vImag256, 256, samplingFrequency); // create FFT object
  FFT.DCRemoval();
  FFT.Windowing(_windowType, FFT_FORWARD);
  FFT.Compute(FFT_FORWARD);
  FFT.ComplexToMagnitude();
  return (uint16_t)FFT.MajorPeak();
}

void *memset(void *s, int c, size_t n);

DESCRIPTION
The memset() function fills the first n bytes of the memory area
pointed to by s with the constant byte c.

In C, you would use memset(samples, 0, sizeof(samples)).
In C++, you would use std::fill(std::begin(samples), std::end(samples), 0).

But this is unnecessary here, since float samples[128] = {} already sets the elements to zero.

Pieter

arduarn:

I should really start reading docu before just using stuff i found online... Thanks

PieterP:
In C, you would use memset(samples, 0, sizeof(samples)).
In C++, you would use std::fill(std::begin(samples), std::end(samples), 0).

But this is unnecessary here, since float samples[128] = {} already sets the elements to zero.

Pieter

Many thanks, doing it this way worked!

EDIT: Said that too early, I still get overflow values when trying to use the library

EDIT2: OK, now it's getting weird. I inserted a Serial.println("Start"); directily after Serial.begin(115200); for debugging, and it only prints "Star" before completely stopping. No operation is called before

Please post your exact code.

I solved the problem by just providing all arrays to the library instead of initializing them in there. This seems to have lead to some conflicting memory access scenarios.

Code now runs fine, so I’m pretty much done with this.

If anyone sees the glaring mistake in there, feel free to post an answer so others can use the resource. Also, I myself would quite like to know what exactly went wrong.

Thanks for all your suggestions! See you.

EDIT:
Last known non-running config:

.ino:

#include "FundamentalFrequencyAnalyzer.h";


void setup() {
  Serial.begin(115200);
  Serial.println("Start");
  FundamentalFrequencyAnalyzer ffa = FundamentalFrequencyAnalyzer();
  Serial.println("ffa created");
  float samples[128] = {};
  memset(samples, 0, sizeof(samples));
  for(int i = 0; i < 128; i++){
    Serial.println(samples[i]);
  }
  boolean b = 0;
  uint8_t j = 0;
  for (int i = 0; i < 128; i++) {
    samples[i] = b;
    if (j >= 16) {
      b ^= 1;
      j = 0;
    }
    j++;
  }
  ffa.get128(samples, 1000);
}

void loop() {

}

.h:

#ifndef FundamentalFrequencyAnalyzer_h
#define FundamentalFrequencyAnalyzer_h

#include "Arduino.h"

#define WIN_TYP_RECTANGLE FFT_WIN_TYP_RECTANGLE
#define WIN_TYP_HAMMING FFT_WIN_TYP_HAMMING
#define WIN_TYP_HANN FFT_WIN_TYP_HANN
#define WIN_TYP_TRIANGLE FFT_WIN_TYP_TRIANGLE
#define WIN_TYP_NUTTALL FFT_WIN_TYP_NUTTALL
#define WIN_TYP_BLACKMAN FFT_WIN_TYP_NUTTALL
#define WIN_TYP_BLACKMAN_NUTTALL FFT_WIN_TYP_BLACKMAN_NUTTALL
#define WIN_TYP_BLACKMAN_HARRIS FFT_WIN_TYP_BLACKMAN_HARRIS
#define WIN_TYP_FLT_TOP FFT_WIN_TYP_FLT_TOP
#define WIN_TYP_WELCH FFT_WIN_TYP_WELCH

class FundamentalFrequencyAnalyzer {
  public:
    FundamentalFrequencyAnalyzer(uint8_t windowType);
    FundamentalFrequencyAnalyzer();
    uint16_t get32(float *samples, uint16_t samplingFrequency);
    uint16_t get64(float *samples, uint16_t samplingFrequency);
    uint16_t get128(float *samples, uint16_t samplingFrequency);
    uint16_t get256(float *samples, uint16_t samplingFrequency);
  private:
    uint8_t _windowType;
    float _vReal32[32] = {};
    float _vImag32[32] = {};
    float _vReal64[64] = {};
    float _vImag64[64] = {};
    float _vReal128[128] = {};
    float _vImag128[128] = {};
    float _vReal256[256] = {};
    float _vImag256[256] = {};
};

#endif

.cpp:

#include "Arduino.h"
#include "src\arduinoFFT.h"
#include "FundamentalFrequencyAnalyzer.h"

FundamentalFrequencyAnalyzer::FundamentalFrequencyAnalyzer(uint8_t windowType)
{
  _windowType = windowType;
}

FundamentalFrequencyAnalyzer::FundamentalFrequencyAnalyzer()
{
  _windowType = WIN_TYP_RECTANGLE;
}

uint16_t FundamentalFrequencyAnalyzer::get32(float *samples, uint16_t samplingFrequency)
{
  memcpy(_vReal32, samples, 32);
  memset(_vImag32, 0, 32);
  arduinoFFT FFT = arduinoFFT(_vReal32, _vImag32, 32, samplingFrequency); // create FFT object
  FFT.DCRemoval();
  FFT.Windowing(_windowType, FFT_FORWARD);
  FFT.Compute(FFT_FORWARD);
  FFT.ComplexToMagnitude();
  return (uint16_t)FFT.MajorPeak();
}

uint16_t FundamentalFrequencyAnalyzer::get64(float *samples, uint16_t samplingFrequency)
{
  memcpy(_vReal64, samples, 64);
  memset(_vImag64, 0, 64);
  arduinoFFT FFT = arduinoFFT(_vReal64, _vImag64, 64, samplingFrequency); // create FFT object
  FFT.DCRemoval();
  FFT.Windowing(_windowType, FFT_FORWARD);
  FFT.Compute(FFT_FORWARD);
  FFT.ComplexToMagnitude();
  return (uint16_t)FFT.MajorPeak();
}

uint16_t FundamentalFrequencyAnalyzer::get128(float *samples, uint16_t samplingFrequency)
{
  memcpy(_vReal128, samples, 128);
  memset(_vImag128, 0, 128);
  arduinoFFT FFT = arduinoFFT(_vReal128, _vImag128, 128, samplingFrequency); // create FFT object
  FFT.DCRemoval();
  FFT.Windowing(_windowType, FFT_FORWARD);
  FFT.Compute(FFT_FORWARD);
  FFT.ComplexToMagnitude();
  return (uint16_t)FFT.MajorPeak();
}

uint16_t FundamentalFrequencyAnalyzer::get256(float *samples, uint16_t samplingFrequency)
{
  memcpy(_vReal256, samples, 256);
  memset(_vImag256, 0, 256);
  arduinoFFT FFT = arduinoFFT(_vReal256, _vImag256, 256, samplingFrequency); // create FFT object
  FFT.DCRemoval();
  FFT.Windowing(_windowType, FFT_FORWARD);
  FFT.Compute(FFT_FORWARD);
  FFT.ComplexToMagnitude();
  return (uint16_t)FFT.MajorPeak();
}