Storing sensor data in an array

I'm attempting to store data, that I'm reading from a hall effect sensor, into an array so that I can print these to serial after running for a while (255 cycles of the loop, ideally I'd like to collect as much data as possible i.e as many cycles). This is because I'm having issues reading the sensor data while simultaneously printing the data. The sensor outputs a PWM signal with a pulse width of 74 μS so printing in the middle of a pulse will cause the loss of some of the data (I believe). Currently, the array is set up as can be seen in the code attached to this post. When I open the serial monitor there is no data being displayed (the monitor doesn't even output zeros).

I am sure that the sensor is working as I have measured this with an oscilloscope and the PWM is outputting constantly. The sensor is also being read by the Arduino as I have printed this with the serial plotter and can see that the signal is being read. Although it seems to be being disrupted and is not a continuous stream of data (again I think this is due to the serial print execution time taking up too much time).

If someone can tell me why the array is not working that would be amazing, I have scoured the internet and this forum but cant seem to find a solution to my problem. I'm using an Arduino due. Thank you ahead of time fellow coders.

#include <DueAdcFast.h>

DueAdcFast DueAdcF(1024);

// 1024 measures is dimension of internal buffer. (min is 1024)

unsigned long period;
unsigned long spaceLength;
unsigned long pulseWidth;
unsigned long oldPeriod = 0;

int inputSignal;
int start1;

unsigned long endTime;
unsigned long lowTime;
unsigned long midTime;

int frequencyINPUT;
volatile int x;
int b;
int y;
int i=0;
int j;
int z;

uint32_t sensorSignal;  // the variables of your code.

float getround; 
int rounded;
int finalval;

int pulseWidths[255];

void setup() {

  start1 = 0;  
 
  Serial.begin(115200);

  // indicate the pins to be used with the library. 
  DueAdcF.EnablePin(A7);
  //DueAdcF.EnablePin(A1);

  // indicate at what speed in the background 

  DueAdcF.Start1Mhz();       // max speed 1Mhz (sampling rate)

  //DueAdcF.Start();         // normal speed 667 Khz (sampling rate)
  
  //DueAdcF.Start(255);      // with prescaler value form 3 to 255.
                             // 255 is approx. 7812 Hz (sampling rate)
 
}


// these 3 lines of code are essential for the functioning of the library
// you don't call ADC_Handler.
// is used automatically by the PDC every time it has filled the buffer
// and rewrite buffer.
// 
void ADC_Handler() {
  DueAdcF.adcHandler();
}


void loop() {

 //y = micros();
 
 sensorSignal = DueAdcF.ReadAnalogPin(A7);  
   
 
  if (sensorSignal < 1800 && start1 == 0) //detects first tooth and starts to read the output signal from the sensor (PART 1 ON DIAGRAM 1.)
  {

    start1=1;
   

  }

  if (sensorSignal > 1800  && start1 == 1)  //reads that the sensor has gone low and records the time  (PART 2 ON DIAGRAM 1.)
  {

    start1=2;
    lowTime = micros()*0.01;  
     

  }

  if (sensorSignal < 1800  && start1 == 2)  //reads that the sensor has gone high and records the time  (PART 3 ON DIAGRAM 1.)
  {

    start1=3;
    midTime = micros()*0.01;

  }
  if (sensorSignal > 1800 && start1 == 3)  //reads that the sensor has gone high and records the time  (PART 1 ON DIAGRAM 1.)
  {

    start1=1;
    endTime = micros()*0.01;
    
    spaceLength = endTime - midTime;
    period = endTime - lowTime;
    pulseWidth = period - spaceLength;
  }  
     
 j = j+1;
  for ( i = 0; i < 254; i = i + 1) {
     pulseWidths[i] = pulseWidth;
    }

  while(j>255)
  {
    
      for ( z = 0; z < 254; z = z + 1) {
      Serial.println(pulseWidths[z]);
      
    }
    }
}

    
    

and when is this true?

Your code starts with variable i being zero. Then, in loop(), you do while (i > 255); so you will never get inside the while-loop.

Do yourself (and us) a favour and don't use single character global variables; I tried to find where the variable i was used by searching the the letter i; 128 matches :frowning:

Apologies this is a simplified version of the code I made to post here (i.e I deleted a lot of the manipulation of the data that happens after the array as this is not relevant) I have changed the code now.

Step through your logic here. What value does I have at the beginning of the "while()? Where do you set it? Then in the following code you use I again in another loop that is imbedded in the first loop. Why?

Paul

My mistake this is a simplified version of the code I made quickly to post here (i.e I deleted a lot of the manipulation of the data that happens after the array as this is not relevant) I have changed the code now. Should have given it a quick proof read before posting, my bad.

so basically as soon as j >255 (after 255 loop iterations) it starts executing prinln 255 times per each further loop iteration. What exactly does this achieve?

So this fills all elements if pulseWidths with the same value. I guess that you want to store the pulseWidth in an element of the array when you have done the reading / calculation. So in here

  if (sensorSignal > 1800 && start1 == 3)  //reads that the sensor has gone high and records the time  (PART 1 ON DIAGRAM 1.)
  {
    start1 = 1;
    endTime = micros() * 0.01;

    spaceLength = endTime - midTime;
    period = endTime - lowTime;
    pulseWidth = period - spaceLength;
  }

Well, I had thought that once j>255 the code would never leave this while loop and would just output the data stored in the array. I realize that the first for loop should have been outside the while loop for this to work but I had tried that previously and I still got the same issue. Like the code below:

#include <DueAdcFast.h>

DueAdcFast DueAdcF(1024);

// 1024 measures is dimension of internal buffer. (min is 1024)

unsigned long period;
unsigned long spaceLength;
unsigned long pulseWidth;
unsigned long oldPeriod = 0;

int inputSignal;
int start1;

unsigned long endTime;
unsigned long lowTime;
unsigned long midTime;

int frequencyINPUT;
volatile int x;
int b;
int y;
int i=0;
int j;
int z;

uint32_t sensorSignal;  // the variables of your code.

float getround; 
int rounded;
int finalval;

int pulseWidths[255];

void setup() {

  start1 = 0;  
 
  Serial.begin(115200);

  // indicate the pins to be used with the library. 
  DueAdcF.EnablePin(A7);
  //DueAdcF.EnablePin(A1);

  // indicate at what speed in the background 

  DueAdcF.Start1Mhz();       // max speed 1Mhz (sampling rate)

  //DueAdcF.Start();         // normal speed 667 Khz (sampling rate)
  
  //DueAdcF.Start(255);      // with prescaler value form 3 to 255.
                             // 255 is approx. 7812 Hz (sampling rate)
 
}


// these 3 lines of code are essential for the functioning of the library
// you don't call ADC_Handler.
// is used automatically by the PDC every time it has filled the buffer
// and rewrite buffer.
// 
void ADC_Handler() {
  DueAdcF.adcHandler();
}


void loop() {

 //y = micros();
 
 sensorSignal = DueAdcF.ReadAnalogPin(A7);  
   
 
  if (sensorSignal < 1800 && start1 == 0) //detects first tooth and starts to read the output signal from the sensor (PART 1 ON DIAGRAM 1.)
  {

    start1=1;
   

  }

  if (sensorSignal > 1800  && start1 == 1)  //reads that the sensor has gone low and records the time  (PART 2 ON DIAGRAM 1.)
  {

    start1=2;
    lowTime = micros()*0.01;  
     

  }

  if (sensorSignal < 1800  && start1 == 2)  //reads that the sensor has gone high and records the time  (PART 3 ON DIAGRAM 1.)
  {

    start1=3;
    midTime = micros()*0.01;

  }
  if (sensorSignal > 1800 && start1 == 3)  //reads that the sensor has gone high and records the time  (PART 1 ON DIAGRAM 1.)
  {

    start1=1;
    endTime = micros()*0.01;
    
    spaceLength = endTime - midTime;
    period = endTime - lowTime;
    pulseWidth = period - spaceLength;
  }  
     i

    Serial.print(sensorSignal);
    Serial.println();

    for ( i = 0; i < 254; i = i + 1) {
     pulseWidths[i] = pulseWidth;
    }

  while(i>255)
  {
       for ( z = 0; z < 254; z = z + 1) {
      Serial.println(pulseWidths[z]);
      
    }
    }
}

    
    

Yeah exactly, I would like to store the value of "pulseWidth" in the array "pulseWidths" going from element 0>254 till the array is full then stop reading the sensor data and serial print the values stored within the array. I believe the measurement of the pulse widths is fluctuating whereas is should be constantly 74 micro seconds (as it is when I measure it with the oscilloscope). But I cannot tell this without saving the data to be read after the loop has ran for a good number of cycles to see if the value pulseWidth changes.

Based on the code in post #9, you can try to understand this and see if it works. I can't compile it.

#include <DueAdcFast.h>

DueAdcFast DueAdcF(1024);

// 1024 measures is dimension of internal buffer. (min is 1024)

unsigned long period;
unsigned long spaceLength;
unsigned long pulseWidth;
unsigned long oldPeriod = 0;

int inputSignal;
int start1;

unsigned long endTime;
unsigned long lowTime;
unsigned long midTime;

int frequencyINPUT;
volatile int x;
int b;
int y;
int arrayIndex = 0;
int j;

uint32_t sensorSignal;  // the variables of your code.

float getround;
int rounded;
int finalval;

int pulseWidths[255];

void setup()
{

  start1 = 0;

  Serial.begin(115200);

  // indicate the pins to be used with the library.
  DueAdcF.EnablePin(A7);
  //DueAdcF.EnablePin(A1);

  // indicate at what speed in the background

  DueAdcF.Start1Mhz();       // max speed 1Mhz (sampling rate)

  //DueAdcF.Start();         // normal speed 667 Khz (sampling rate)

  //DueAdcF.Start(255);      // with prescaler value form 3 to 255.
  // 255 is approx. 7812 Hz (sampling rate)

}


// these 3 lines of code are essential for the functioning of the library
// you don't call ADC_Handler.
// is used automatically by the PDC every time it has filled the buffer
// and rewrite buffer.
//
void ADC_Handler() {
  DueAdcF.adcHandler();
}


void loop()
{
  sensorSignal = DueAdcF.ReadAnalogPin(A7);

  if (sensorSignal < 1800 && start1 == 0) //detects first tooth and starts to read the output signal from the sensor (PART 1 ON DIAGRAM 1.)
  {
    start1 = 1;
  }

  if (sensorSignal > 1800  && start1 == 1)  //reads that the sensor has gone low and records the time  (PART 2 ON DIAGRAM 1.)
  {
    start1 = 2;
    lowTime = micros() * 0.01;
  }

  if (sensorSignal < 1800  && start1 == 2)  //reads that the sensor has gone high and records the time  (PART 3 ON DIAGRAM 1.)
  {
    start1 = 3;
    midTime = micros() * 0.01;
  }
  if (sensorSignal > 1800 && start1 == 3)  //reads that the sensor has gone high and records the time  (PART 1 ON DIAGRAM 1.)
  {
    start1 = 1;
    endTime = micros() * 0.01;

    spaceLength = endTime - midTime;
    period = endTime - lowTime;
    pulseWidth = period - spaceLength;

    pulseWidths[arrayIndex++] = pulseWidth;
  }

  Serial.print(sensorSignal);
  Serial.println();

  if (arrayIndex > 255)
  {
    for (int z = 0; z < 255; z = z + 1)
    {
      Serial.println(pulseWidths[z]);
    }
    arrayIndex = 0;
  }
}

Please note that i was renamed to arrayIndex (a name that covers the purpuse of the variable) and z was removed from the global section. I haven't looked at other variables.

Hi sterretje, that code is working perfectly thank you for your help. I must have been reading out of date information on the variable used to index the array. Thank you so much for your help it is much appreciated.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.