Overwriting values in an array using for loop

Hi all,

I know this is probably a very easy fix (and yes i am new to this). However, i can't seem to figure out how to stop writing over values using an array. I am using an UNO

Here's what i am trying to do:
Writing a code to store the elapsed time since a voltage of zero was read (24 times).

Here's my code (forgive me):

float dataA0 = 0;
float VoltA0 = 0;

void loop()
{
//Read input from analog shield Channel A0 (Phase A) and return the time it crosses over OV.
  dataA0 = analogRead(0);
  VoltA0 = (((dataA0 / 203.8)));

// Timing for phase A crossovers
  unsigned long T_PhaseAcross[23];
  for (int i = 0; i <= 23; i++) {

    if (VoltA0 <= 0.05)
    {
      T_PhaseAcross[i] = millis();
      Serial.print("T_PhaseA_");
      Serial.print(i);
      Serial.print(" = ");
      Serial.print(T_PhaseAcross[i]);
      Serial.print("\n");
      delay(10);
    }
  }
}

And my output is somewhere along the lines of:

T_PhaseA_0 = 6300
T_PhaseA_1 = 6310
T_PhaseA_2 = 6322
T_PhaseA_3 = 6332
T_PhaseA_4 = 6342
T_PhaseA_5 = 6352
T_PhaseA_6 = 6363
T_PhaseA_7 = 6374
T_PhaseA_8 = 6392
T_PhaseA_9 = 6412
T_PhaseA_10 = 6430
T_PhaseA_11 = 6450
T_PhaseA_12 = 6470
T_PhaseA_13 = 6490
T_PhaseA_14 = 6509
T_PhaseA_15 = 6529
T_PhaseA_16 = 6549
T_PhaseA_17 = 6568
T_PhaseA_18 = 6588
T_PhaseA_19 = 6608
T_PhaseA_20 = 6628
T_PhaseA_21 = 6647
T_PhaseA_22 = 6667
T_PhaseA_23 = 6687
T_PhaseA_0 = 6779
T_PhaseA_1 = 6790
T_PhaseA_2 = 6800
T_PhaseA_3 = 6810
T_PhaseA_4 = 6821 ...

I am wanting it to simply stop at T_PhaseA_23. Is the problem that i have it in the main loop? Do i need to make this last portion a separate function?

When loop() ends, it is started over again from the beginning. That is its purpose. Put the whole stuff into setup() and leave loop() empty.
This is surely not all of your sketch. If you want to do something with the data you acquired then make a function that fills the array and call that function whenever you need to

olf2012:
Put the whole stuff into setup() and leave loop() empty.

I need to continuously monitor that voltage level though. If i put everything into setup, i only take a one time voltage reading.

KBarnett:
I need to continuously monitor that voltage level though. If i put everything into setup, i only take a one time voltage reading.

Um, put the reading into the for loop?

Your understanding of for loops is lacking or wrong.

Explain your program- there doesn't seem to be any point to it. If VoltA0 meets your condition, you're just printing predictable garbage 23 times before VoltA0 updates again.

If you want it to print that junk 23 times and then ignore the fact that the if condition is still being met.... how do you expect it to keep monitoring? Do you want it to wait until VoltA0 gets above 0.05, THEN care if it goes back below? If so, then code it to do so.

Writing a code to store the elapsed time since a voltage of zero was read (24 times).

If I understand you correctly you want to know the time it takes to get 24 0V readings. You don't need an array for that but a counter and a millis() based timing

Something like below will probably work

void loop()
{
  static byte counter = 0;
  static unsigned long startTime = 0;

  // if no start time set, set to current time
  if (startTime == 0)
  {
    startTime = millis();
  }

  //Read input from analog shield Channel A0 (Phase A) and return the time it crosses over OV.
  dataA0 = analogRead(0);
  VoltA0 = (((dataA0 / 203.8)));

  // if 0V. increment counter
  if (VoltA0 <= 0.05)
  {
    counter++;
  }

  // if
  if (counter == 23)
  {
    Serial.print("24 times 0V detected in ");
    Serial.print(millis() - startTime);
    Serial.println("ms");

    counter = 0;
    startTime = 0;
  }
}

To play it safe, you need to add a delay of 1ms in setup so a measured start time will never be 0.

Let me explain a little further as it seems i wasn't clear the first time.

I am trying to program a hall sensor - motor phase alignment tester. My approach (initially) is to have A0 read the input from motor phase A continuously and document and store the time intervals (i realize it should have include in my program an interval time) for the first 24 crossover (0V) points for that phase. Then i will take an average of these intervals

A1 will be doing a similar process for one of the hall sensors. Once i take the 24 cross over points / time intervals and average them, i will be able to see the difference (converting to electrical degrees) in hall sensor alignment to motor phases.

And yes this will be done with the other phases and hall sensors as well. That's a brief overview of what I am trying to accomplish. I appreciate all that are really trying to help.

There is no such thing as reading continuously. And with your use of delay, there is no hope of getting anything useful with any of it so far.

Your code literally goes

-read A0
-print stuff for about half a second (all 23 lines) while NOT updating A0
-read A0 again
-print stuff for about half a second (all 23 lines again)
etc.

What kind of frequency are you dealing with? Do you know if the Arduino is fast enough to detect? What do you mean crossover (0V)? Are you expecting negative voltage?

To start, you need to be reading every single loop. As it stands, a single instance of <=0.05 triggers a meaningless print of 23 values only separated by your 10ms delay and however long it takes to print. That data in no way represents any phases.

INTP:
There is no such thing as reading continuously. And with your use of delay, there is no hope of getting anything useful with any of it so far.

Your code literally goes

-read A0
-print stuff for about half a second (all 23 lines) while NOT updating A0
-read A0 again
-print stuff for about half a second (all 23 lines again)
etc.

What kind of frequency are you dealing with? Do you know if the Arduino is fast enough to detect? What do you mean crossover (0V)? Are you expecting negative voltage?

To start, you need to be reading every single loop. As it stands, a single instance of <=0.05 triggers a meaningless print of 23 values only separated by your 10ms delay and however long it takes to print. That data in no way represents any phases.

Thank you for your explanation, that was helpful. I mistakenly said crossover voltage. Yes i've checked (as well as others) that the arduino is capable of handling this project. I see what you mean about not updating the voltage every time through the loop. Here's my updated code. Thoughts? I still dont seem to be getting an accurate timing for my outputs.

#include <Adafruit_FT6206.h>

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <gfxfont.h>
#include <Adafruit_ILI9341.h>
#include <SPI.h>



// The display also uses hardware SPI, plus #9 & #10
#define TFT_CS 10
#define TFT_DC 9
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
Adafruit_FT6206 ctp = Adafruit_FT6206();

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

boolean CrossOverPt = false;

#define FRAME_X 60   // X coordinate for the "Press to Begin" button
#define FRAME_Y 110  // Y coordinate for the "Press to Begin" button
#define FRAME_W 200  // Width for the "Press to Begin" button
#define FRAME_H 50   // Height for the "Press to Begin" button
#define FRAME1_X 20  // X coordinate for the "??????" banner
#define FRAME1_Y 5   // Y coordinate for the "???????" banner
#define FRAME1_W 280 // Width for the "????????" banner
#define FRAME1_H 50  // Height for the "????????" banner

int SetupDelay = 3000; //Delay time (3s) for Setup Screen (??????? - Hall Sensor Alignment Test) to Display.



//                                                                                             Setup()
//****************************************************************************************************************************************************************************
void setup()
{

  Serial.begin(9600); // Starting the serial monitor/plotter - Baud rate = 9600
  tft.begin();  // Start use of Adafruit TFT 2.8" Capacitive Touchscreen
  if (!ctp.begin(40)) {
    Serial.println("Unable to start touchscreen."); // If the Touchscreen is not connected, the previous message will display on the serial monitor
  }
  else {
    Serial.println("Touchscreen started."); // If the Touchscreen is connected, the previous message will display on the serial monitor
  }

  tft.fillScreen(ILI9341_BLUE); // Fills the entire screen blue
  // origin = left,top landscape (USB left upper)
  tft.setRotation(1); // Rotate the screen to use horizontally
  drawFrame(); // Calls the drawFrame function - Fills in the buttons and outlines for the setup screen
  addText();  // Calls the addText function - Adds all text to the setup screen
  //delay(SetupDelay); // Delays the next action for 3s
  tft.fillScreen(ILI9341_BLACK); // Fills the entire screen blue
  analog0();


}//                                                                                        End of Setup()
//****************************************************************************************************************************************************************************
//                                                                                             Loop()
//****************************************************************************************************************************************************************************
void loop()
{
}

//                                                                                           End of Loop()
//****************************************************************************************************************************************************************************
//                                                                                             Functions()
//************************************************************************************************************************************************************************************************************
void drawFrame()
{
  tft.fillRect(FRAME1_X, FRAME1_Y, FRAME1_W, FRAME1_H, ILI9341_WHITE);
  tft.drawRect(FRAME1_X, FRAME1_Y, FRAME1_W, FRAME1_H, ILI9341_BLACK);
  tft.drawLine(0, 75, 320, 75, ILI9341_WHITE);
  tft.drawLine(0, 58, 320, 58, ILI9341_WHITE);
  tft.fillRect(FRAME_X, FRAME_Y, FRAME_W, FRAME_H, ILI9341_BLACK);
  tft.drawRect(FRAME_X, FRAME_Y, FRAME_W, FRAME_H, ILI9341_WHITE);
  tft.drawRect(0, 0, 320, 240, ILI9341_BLACK);
}

void addText()
{
  tft.setCursor(45, 20);
  tft.setTextColor(ILI9341_BLUE);
  tft.setTextSize(3);
  tft.print("???????");
  tft.setCursor(5, 60);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);
  tft.print("Hall Sensor Alignment Test");
  tft.setCursor(75, 125);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);
  tft.print("Press to Begin");
  tft.setCursor(180, 230);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);
  tft.print("DEVELOPED JULY 14, 2017");
}

void analog0()
{
  //Read input from analog shield Channel A0 (Phase A) and return the time it crosses over 0V.
  // Timing for phase A crossovers
  unsigned long T_PhaseAcross[23]; // Array holding the intervals for crossover (0V) times.
 /* for (int n = 1; n <= 1; n++) { // For loop to ensure that this sequence is only initiated once (only fill in the values of the array for one full cycle)
    //Serial.print("n = "); //Used for debugging purposes only
    //Serial.println(n);*/
    float VoltA0 = (analogRead(0)) / 203.8; //Modified (203.8 w/out screen - 210 with screen?? KB 07/19/17) from 204.8 for resolution tuning;
    if (VoltA0 <= 0.05) { // Ensures proper timing that first reading will fall directly on a falling/rising edge when Voltage is 0.
      delay(10);
      Serial.println("Delayed");
    }
    int i = 0;
    while (i <= 24) { // While loop to fill in the Array with the 25 interval values
      VoltA0 = (analogRead(0)) / 203.8; //Modified (203.8 w/out screen - 210 with screen?? KB 07/19/17) from 204.8 for resolution tuning;
      unsigned long currentMillis = millis(); // Starts a timer in milleseconds
      unsigned long previousMillis;
      //Serial.print("i = "); //Used for debugging purposes only
      // Serial.println(i);
      if (VoltA0 <= 0.05) {
        CrossOverPt = true;
        T_PhaseAcross[i] = currentMillis - previousMillis; // Interval timing to get 24 crossover points
        previousMillis = currentMillis;
        Serial.print("T_PhaseAcross"); //Used for debugging purposes only
        Serial.print(i);
        Serial.print(" = ");
        Serial.println(T_PhaseAcross[i]);
        i++;
        


      }

    }
    int avg = (T_PhaseAcross[4] + T_PhaseAcross[6] + T_PhaseAcross[8] + T_PhaseAcross[10] + T_PhaseAcross[12] + T_PhaseAcross[14] + T_PhaseAcross[16] + T_PhaseAcross[18] + T_PhaseAcross[20] + T_PhaseAcross[22] + T_PhaseAcross[24]) / 11;
    Serial.print("Average = ");
    Serial.print(avg);
    Serial.println(" ms");
  }
}

//                                                                                    End of Functions()
//****************************************************************************************************************************************************************************