Like for loop iteration with specific period

Hello,

For my project, I want to design this situation as a code in Arduino.
I want to make a code to describe that integer I will increase until 127 with a specific time (like 50ms). I call this specific time as duration time.
Meanwhile, integer J will start rising a few milliseconds (defined as specific onset time (SOT)) after integer I starts rising. Both of integers have same duration time. But there is a difference between starting time.

Integer I will increase from 0 to 127. When I =127, the time should be 50ms.
Integer J will start increasing from 0 to 127 after a few milliseconds (SOT, for example 40ms) after integer I starts rising.

For this situation, how to make the code?
This is the my sample code.

unsigned long previousMillis = 0;
const long interval = 100;
int i = 0;
int j = 0;

bool i_decreasing = false;
bool j_decreasing = false; // 
void setup() {
  // put your setup code here, to run once:
   Serial.begin(9600);

}

void loop() {
  unsigned long currentMills = millis();
  if(!i_decreasing&&i<127){
    Serial.println("I");
    Serial.println(i);
    if (currentMills-previousMillis>=interval){
      previousMillis = currentMills;
       j++;
      Serial.println(j);
    }
    if (i== 127){
      i_decreasing = true; 
    }
  }
  if(i_decreasing && i>0){
      I--;
      j++;
       Serial.println(i);
      Serial.println(j);
      if (j==127){
        j_decreasing = true; 
      }
   }
   if(j_decreasing && j>0){
    j--;
    Serial.println("j");
    Serial.println(j);
   }

  
  // put your main code here, to run repeatedly:

}

Hello kylerhong

Welcome to the worldbest forum.

We need some additional information.
Post your sketch, well formated, with well-tempered comments and in so called code tags and a real schematic to see how we can help.

Have a nice day and enjoy coding in C++.
Paul

The description is not very clear. Could You express the happening in a graphical way?

1 Like

Draw a graph of the two signals versus time.

What happens after the point where both are at 127?

BTW i, I, j and J are not good variable names. Trust us and use a few more if your lifetime allowance of letters and numbers in naming things.

When you start writing sketches even a bit logner or more complicate, you will thank us. :expressionless:

It would not hurt for you to say what this is for.

a7'

When taking 127 steps in 50 milliseconds you will need timing with higher resolution than millis(). Perhaps micros() will be a good choice.

unsigned long IntervalInMicros = 50000ul / 127;
int DelaySteps = 40000ul / IntervalInMicros;

int Signal_I = 0;
int Signal_J = 0;
void setup()
{
}

void loop()
{
  unsigned long currentMicros = micros();
  static unsigned long lastStepTime = micros();

  if (currentMicros - lastStepTime >= IntervalInMicros)
  {
    lastStepTime += IntervalInMicros;
    if (Signal_I < 127)
      Signal_I++;

    if (Signal_I > DelaySteps)
      if (Signal_J < 127)
        Signal_J++;
  }
}

Here is what I want to describe.

1 Like

So some kind of curve, not linear ramps? And to go back to 0 after reaching the maximum value?

Does anything ever make it repeat?

See how different what you ask for now is from what you first said?

a7

1 Like

Would the positive half of a sine curve, like 127*sin(2.0*PI*millis()/200.0) and 127*sin(2.0*PI*(millis() - 40.0)/200.0) work?

It doesn't need to look like a curve function. It is just an example of what I want to describe.
Furthermore, after reaching the max value, it will go back to 0.
This figure is exactly what I want to describe.

Except straight lines up and down, not curves.

You haven't said if anything makes that happen again.

a7

1 Like

It doesn't matter whether it is a curve or a straight line.
For the question if anything makes that happen again,
first of all, I don't need to happen it again.
But if you can provide more sample code to repeat it, would you like to provide it also?

unsigned long IntervalInMicros = 50000ul / 127;
int DelaySteps = 40000ul / IntervalInMicros;

byte i = 0;
byte j = 0;

bool i_Going_Up = true;
bool j_Going_Up = true;

void setup()
{
}

void loop()
{
  unsigned long currentMicros = micros();
  static unsigned long lastStepTime = micros();

  if (currentMicros - lastStepTime >= IntervalInMicros)
  {
    lastStepTime += IntervalInMicros;
    if (i_Going_Up)
    {
      if (i < 127)
        i++;
      else
        i_Going_Up = false;
    }
    else
    {
      if (i > 0)
        i--;
    }

    if (!i_Going_Up || i > DelaySteps)
    {
      if (j_Going_Up)
      {
        if (j < 127)
          j++;
        else
          j_Going_Up = false;
      }
      else
      {
        if (j > 0)
          j--;
      }
    }
  }
}
1 Like

When I printed out the currentmicros and compare when I= 0 and i=127, it is not exact time (50ms). It is almost 3 seconds. Is this what I want to describe as I have shown before?

DO you have any idea?

Sure. Post the code you are talking about in your post #13 above.

a7

That is the code johnwasser uploaded?

No, you added printing to it. Who knows what else you changed?

Post the actual code you used that prints out the wrong time taken to do whatever.

a7

1 Like

I mean can you provide the code to describe what I described using illustration?

@johnwasser 's code seems to meet the requirements as stated.

unsigned long IntervalInMicros = 50000ul / 127;
int DelaySteps = 40000ul / IntervalInMicros;

byte i = 0;
byte j = 0;

bool i_Going_Up = true;
bool j_Going_Up = true;

bool iPeaked = false;
bool jPeaked = false;


void setup()
{
  Serial.begin(115200);
}

void loop()
{
  unsigned long currentMicros = micros();
  static unsigned long lastStepTime = micros();

  if (currentMicros - lastStepTime >= IntervalInMicros)
  {
    lastStepTime += IntervalInMicros;
    if (i_Going_Up)
    {
      if (i < 127)
        i++;
      else
        i_Going_Up = false;
    }
    else
    {
      if (i > 0)
        i--;
    }

    if (!i_Going_Up || i > DelaySteps)
    {
      if (j_Going_Up)
      {
        if (j < 127)
          j++;
        else
          j_Going_Up = false;
      }
      else
      {
        if (j > 0)
          j--;
      }
    }
  }
  if(i == 127){
    Serial.print("Imid:");
    Serial.println(currentMicros);
    iPeaked = true;
  }
  if(j == 127){
    Serial.print("Jmid:");
    Serial.println(currentMicros);
    jPeaked = true;

  }

  if(iPeaked && i == 0){
    Serial.print("Iend:");
    Serial.println(currentMicros);
    iPeaked = false;
  }

  if(jPeaked && j == 0){
    Serial.print("Jend:");
    Serial.println(currentMicros);
    jPeaked = false;
  }
}

...gets me these microsecond timestamps for the peaks and ends:

Imid:49924
Imid:50252
Imid:50580
Jmid:89616
Jmid:89936
Jmid:90268
Iend:100228
Jend:139920

How did you do your test printing to get 3 seconds?

1 Like
unsigned long IntervalInMicros = 50000ul / 127;
int DelaySteps = 40000ul / IntervalInMicros;

byte i = 0;
byte j = 0;

bool i_Going_Up = true;
bool j_Going_Up = true;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  unsigned long currentMicros = micros();
  static unsigned long lastStepTime = micros();
  Serial.println(String(currentMicros));
  if (currentMicros - lastStepTime >= IntervalInMicros)
  {
    Serial.println(String(currentMicros));
    lastStepTime += IntervalInMicros;
    if (i_Going_Up)
    {
      if (i < 127){
        i++;
        Serial.println("i");
        Serial.println(i);
        }
        
      else{
        i_Going_Up = false;}
    }
    else
    {
      if (i > 0){
        i--;}
    }

    if (!i_Going_Up || i > DelaySteps)
    {
      if (j_Going_Up)
      {
        if (j < 127){
          j++;}
        else{
          j_Going_Up = false;}
      }
      else
      {
        if (j > 0){
          j--;}
      }
    }
  }
}

This is what I did. I thought that when printing out currentMicro at 127 and 0, the time difference should be 50ms. but it is not... I am just curious about it .