Having a continuously running loop until the value changes

Hello

I am writing a program that reads an input signal, and outputs a square wave with the same frequency. The flow of the program is as follows:

in the void loop() cycle:
→ Sample a few milliseconds of the input signal
→ Calculate the fundamental frequency
→ Cycle the output pin high/low to correspond to this frequency
→ Repeat

Here’s the code, it’s ugly, but it’s what I have so far.

int analogPin = 3; //Declare the input pin
float inputVals[150]; //Create the array to store values
float sweepVals[75];
float envelope[50][2];
float currentVal = 0.0;
int timeVals[50];
float sum_delta_p;

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  // Record data for 0.02 seconds (enough sampling time to capture low E string)
  // inputVals has 600 samples, so delay each sample by 0.02s/600sa = 0.00004 s = 40 uS

  //read and store the voltage
  for (int i = 0; i < 150; i++) {
    delayMicroseconds(40);
    inputVals[i] = analogRead(analogPin);
  }

  //stores half the sample of the record
  for (int i = 0; i < 75; i++) {
    sweepVals[i] = inputVals[i];
  }

  for (int j = 0; j < 50; j++) {
    currentVal = 0.0;

    for (int i = 0; i + 74 < 150; i++) {
      currentVal += sweepVals[0] * inputVals[i + 0];
      currentVal += sweepVals[1] * inputVals[i + 1];
      currentVal += sweepVals[2] * inputVals[i + 2];
      currentVal += sweepVals[3] * inputVals[i + 3];
      currentVal += sweepVals[4] * inputVals[i + 4];
      currentVal += sweepVals[5] * inputVals[i + 5];
      currentVal += sweepVals[6] * inputVals[i + 6];
      currentVal += sweepVals[7] * inputVals[i + 7];
      currentVal += sweepVals[8] * inputVals[i + 8];
      currentVal += sweepVals[9] * inputVals[i + 9];
      currentVal += sweepVals[10] * inputVals[i + 10];
      currentVal += sweepVals[11] * inputVals[i + 11];
      currentVal += sweepVals[12] * inputVals[i + 12];
      currentVal += sweepVals[13] * inputVals[i + 13];
      currentVal += sweepVals[14] * inputVals[i + 14];
      currentVal += sweepVals[15] * inputVals[i + 15];
      currentVal += sweepVals[16] * inputVals[i + 16];
      currentVal += sweepVals[17] * inputVals[i + 17];
      currentVal += sweepVals[18] * inputVals[i + 18];
      currentVal += sweepVals[19] * inputVals[i + 19];
      currentVal += sweepVals[20] * inputVals[i + 20];
      currentVal += sweepVals[21] * inputVals[i + 21];
      currentVal += sweepVals[22] * inputVals[i + 22];
      currentVal += sweepVals[23] * inputVals[i + 23];
      currentVal += sweepVals[24] * inputVals[i + 24];
      currentVal += sweepVals[25] * inputVals[i + 25];
      currentVal += sweepVals[26] * inputVals[i + 26];
      currentVal += sweepVals[27] * inputVals[i + 27];
      currentVal += sweepVals[28] * inputVals[i + 28];
      currentVal += sweepVals[29] * inputVals[i + 29];
      currentVal += sweepVals[30] * inputVals[i + 30];
      currentVal += sweepVals[31] * inputVals[i + 31];
      currentVal += sweepVals[32] * inputVals[i + 32];
      currentVal += sweepVals[33] * inputVals[i + 33];
      currentVal += sweepVals[34] * inputVals[i + 34];
      currentVal += sweepVals[35] * inputVals[i + 35];
      currentVal += sweepVals[36] * inputVals[i + 36];
      currentVal += sweepVals[37] * inputVals[i + 37];
      currentVal += sweepVals[38] * inputVals[i + 38];
      currentVal += sweepVals[39] * inputVals[i + 39];
      currentVal += sweepVals[40] * inputVals[i + 40];
      currentVal += sweepVals[41] * inputVals[i + 41];
      currentVal += sweepVals[42] * inputVals[i + 42];
      currentVal += sweepVals[43] * inputVals[i + 43];
      currentVal += sweepVals[44] * inputVals[i + 44];
      currentVal += sweepVals[45] * inputVals[i + 45];
      currentVal += sweepVals[46] * inputVals[i + 46];
      currentVal += sweepVals[47] * inputVals[i + 47];
      currentVal += sweepVals[48] * inputVals[i + 48];
      currentVal += sweepVals[49] * inputVals[i + 49];
      currentVal += sweepVals[50] * inputVals[i + 50];
      currentVal += sweepVals[51] * inputVals[i + 51];
      currentVal += sweepVals[52] * inputVals[i + 52];
      currentVal += sweepVals[53] * inputVals[i + 53];
      currentVal += sweepVals[54] * inputVals[i + 54];
      currentVal += sweepVals[55] * inputVals[i + 55];
      currentVal += sweepVals[56] * inputVals[i + 56];
      currentVal += sweepVals[57] * inputVals[i + 57];
      currentVal += sweepVals[58] * inputVals[i + 58];
      currentVal += sweepVals[59] * inputVals[i + 59];
      currentVal += sweepVals[60] * inputVals[i + 60];
      currentVal += sweepVals[61] * inputVals[i + 61];
      currentVal += sweepVals[62] * inputVals[i + 62];
      currentVal += sweepVals[63] * inputVals[i + 63];
      currentVal += sweepVals[64] * inputVals[i + 64];
      currentVal += sweepVals[65] * inputVals[i + 65];
      currentVal += sweepVals[66] * inputVals[i + 66];
      currentVal += sweepVals[67] * inputVals[i + 67];
      currentVal += sweepVals[68] * inputVals[i + 68];
      currentVal += sweepVals[69] * inputVals[i + 69];
      currentVal += sweepVals[70] * inputVals[i + 70];
      currentVal += sweepVals[71] * inputVals[i + 71];
      currentVal += sweepVals[72] * inputVals[i + 72];
      currentVal += sweepVals[73] * inputVals[i + 73];
      currentVal += sweepVals[74] * inputVals[i + 74];

    }
    envelope[j][1] = currentVal;
    envelope[j][2] = micros();
  }
  for (int i = 0; i < 50; i++) {
    if ((envelope[i][1] > envelope[i - 1][1]) && (envelope[i][1] > envelope[i + 1][1])) {
      timeVals[i] = envelope[i][2];
    }
  }
  sum_delta_p = 0;
  for (int i = 0; i < 50; i++) {
    sum_delta_p += timeVals[i];
  }

}

The last loop calculates the sum of time values, which will be used in the calculation of the fundamental frequency. Like I said, it’s not done yet.

However, I was the output pin the cycle continuously, even while the program is reading the new input signal. If I put the high/low cycle in a do while loop and set the while condition to always be true (i.e. do while 1=1), then it would theoretically get stuck on the first pass through that it does.

Is there any way around this?

Post the code. There's no reason you can't sample your input at the same time you're toggling the output. The loop starts to look differently.

--- Check input state, if it has changed then do calculations for frequency
--- Check time against micros or millis to see if it is time to toggle the output pin. (Blink Without Delay style)

In the part where you are doing the frequency calculations you can decide whether or not to change the frequency of your output pin.

secretempire1:
If I put the high/low cycle in a do while loop

In general do not use FOR or WHILE loops for anything that takes longer than a millsec. Use IF and allow loop() to do the repetition. Have a look at the demo Several Things at a Time. Note how each function runs very briefly and returns to loop() so the next one can be called. And there may be dozens of calls to a function before it is actually time for it to do anything.

...R

Added the code

secretempire1:
Added the code

Please don’t make big changes to existing Posts - correcting typos is fine. But new material should have been in your Reply #3 to maintain the normal flow of the discussion.

Also, to make it easy for people to help you please modify your post and use the code button </>

so your code looks like this

and is easy to copy to a text editor. See How to use the Forum

Your code is too long for me to study quickly without copying to a text editor.

This sort of program writing is madness

for (int i = 0; i + 74 < 150; i++) {
      currentVal += sweepVals[0] * inputVals[i + 0];
      currentVal += sweepVals[1] * inputVals[i + 1];
      currentVal += sweepVals[2] * inputVals[i + 2];
      currentVal += sweepVals[3] * inputVals[i + 3];
      currentVal += sweepVals[4] * inputVals[i + 4];

Why not just

for (int i = 0; i <= 74; i++) {
      currentVal += sweepVals[i] * inputVals[i + i];
}

…R

Robin2:
This sort of program writing is madness

for (int i = 0; i + 74 < 150; i++) {

currentVal += sweepVals[0] * inputVals[i + 0];
      currentVal += sweepVals[1] * inputVals[i + 1];
      currentVal += sweepVals[2] * inputVals[i + 2];
      currentVal += sweepVals[3] * inputVals[i + 3];
      currentVal += sweepVals[4] * inputVals[i + 4];




Why not just


for (int i = 0; 1 <= 74; i++) {
      currentVal += sweepVals[i] * inputVals[i + i];
}




...R

I thought about that, but that wouldn’t accomplish what I want. Take the simplest case, just the first line of that loop. The current way it is, each loop will do
sweepVals[0] * inputVals[0]
sweepVals[0] * inputVals[1]
sweepVals[0] * inputVals[2], etc,

which is what I want.

The way you described (I’m assuming you mean i <= 74, not 1 <= 74) would do

sweepVals[0] * inputVals[0]
sweepVals[1] * inputVals[2]
sweepVals[2] * inputVals[4]

I wonder if you have your two FOR loops interleaved the wrong way. Think about this possibility

for (int i = 0; i + 74 < 150; i++) {

  for (int j = 0; j < 50; j++) {

It has to be possible to do what you want without writer’s cramp :slight_smile:

I also suspect this is a case where using meaningful names rather than i and j would make the solution more obvious.

…R