Easing an Integer to a specific value?

Hey guys!

I am working on some helper functions for a class I am making, one of which eases an int to a specific value over time. However, I cannot figure out how to achieve this with my current code. Here is the function:

void easeAll(int red, int green, int blue, int time, int ledToUsePrevValue)
{
  int prevRedValue = ledStates[ledToUsePrevValue][0];
  int prevBlueValue = ledStates[ledToUsePrevValue][1];
  int prevGreenValue = ledStates[ledToUsePrevValue][2];
  
  int redDiff = red - prevRedValue;
  int blueDiff = blue - prevBlueValue;
  int greenDiff = green - prevGreenValue;
  
  int redStep = redDiff / red;
  int blueStep = blueDiff / blue;
  int greenStep = greenDiff / green;
  
  for(int i = 0; i <= time; i++)
  {
    for(int b = 0; b <= __numLedsInArray; b++)
      {
      ledStates[b][0] =- redStep;
      ledStates[b][1] =- blueStep;
      ledStates[b][2] =- greenStep;
      }
      delay(1);
  }
}

If anybody can help me, that would be great. Or should I just start with a function that eases only 1 value at a time, in a fixed amount of time?

Thank you!

The following statement sets the value of ledStates**[0] equal to -redStep.**
** **ledStates[b][0] =- redStep;** **
If you want to subtract the value of redStep from the current value, use "-=", not "=-"
Regards,
Dave

Oh! Haha yea that would help wouldent it?

while(hasHand)
{
myHand.location = foreHead.location;
myHand.location = myHand.prevLoc;
delay(1) //Allow plenty of time to get hand away from forehead
}

New code (still dosent work. Do you see any problems?) :

void easeAllRed(int red, int ledToUsePrevValue, int millisToRun)
{
    int prevRedValue = ledStates[ledToUsePrevValue][0];
    
    int redDiff = red - prevRedValue;
    
    int loopsToRun = 100;
    
    long redStep = redDiff/loopsToRun;
    Serial.print("redStep: ");
    Serial.println(redStep);
    Serial.println(redDiff);
    for(int i; i<=loopsToRun; i++)
    {
      for(int b = 0; b <= __numLedsInArray; b++)
      {
      ledStates[b][0] += (int)redStep;
      //Serial.print("The red LED is at state: ");
      //Serial.println(ledStates[0][0]);
      if(ledStates[0][0] == red)
      {
        return;
      }
      delay(millisToRun/loopsToRun);
    }
    
}
}

If I figure out a fix, ill post!

int redDiff = red - prevRedValue;

    int loopsToRun = 100;

    long redStep = redDiff/loopsToRun;

If redDiff is an int, and redStep is a smaller value (after all, it is 1% of the value in redDiff), why is redStep a long?

What are sample inputs to easeAllRed()? Why does easing depend on the number of LEDs?

The values in ledStates[x][y] are changed, but not used to control anything.What is the purpose of this function? All it seems to accomplish is a variable delay, depending on the input value of red versus ledStates[0][0].

OK, This code works. Just have to speed up the ISR to reduce flicker ;D

void easeAllRed(int red, int ledToUsePrevValue)
{   
    int redDiff = red - ledStates[ledToUsePrevValue][0];
    int loopsToRun = 100;
    float redStep = (float)redDiff/(float)loopsToRun;
    float redBuffer = ledStates[ledToUsePrevValue][0];
    /* //Uncomment this to debug
    Serial.print("Red is currently: ");
    Serial.println(ledStates[ledToUsePrevValue][0]);
    Serial.print("Red will ease to: ");
    Serial.println(red);
    Serial.print("The number of loops to run is: ");
    Serial.println(loopsToRun);
    Serial.print("redStep: ");
    Serial.println(redStep);
    Serial.print("redDiff: ");
    Serial.println(redDiff);
    */
    for(int i = 0; i<=loopsToRun; i++)
    {
      redBuffer += redStep;
      //Serial.println(redBuffer);
      for(int b = 0; b <= __numLedsInArray; b++)
      {
      ledStates[b][0] = redBuffer;
      //Serial.print("The red LED is at state: ");
      //Serial.println(ledStates[0][0]);
      delayMicroseconds(15);
      }
  }
  for(int b = 0; b <= __numLedsInArray; b++)
  {
  ledStates[b][0] == red;
  }
  //Serial.println("-------");
  return;
}

Yay! Ill work on variable time later, its not needed right now as my top priority is speeding up the ISR :slight_smile:

Yay! Ill work on variable time later, its not needed right now as my top priority is speeding up the ISR

I should hope so. Using delay, of any sort, in an ISR is NOT a good idea, whether using delay(), delayMiscroseconds, or NOP io.

What happens when another interrupt arrives before you have finished servicing the last one?

I should hope so. Using delay, of any sort, in an ISR is NOT a good idea, whether using delay(), delayMiscroseconds, or NOP io.

The delay is not in the ISR. This just modifies the variables in a easy, eye pleasing way for the ISR to use to update the shift registers holding the RGB LEDS.

The ISR is very linear in its run path (it dosent change the number of loops it runs or anything), so it always has the same runtime.

Here is my ISR setup code:

void setupTimer() //Set up the ISR. 
{
  unsigned int tcnt2;

  TIMSK2 &= ~(1<<TOIE2);


  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
  TCCR2B &= ~(1<<WGM22);

  ASSR &= ~(1<<AS2);

  TIMSK2 &= ~(1<<OCIE2A);

  TCCR2B |= (1<<CS22)  | (1<<CS21) | (1<<CS20); // Set bits
  //
  //TCCR2B &= ~(1<<CS21);         
  //TCCR2B &= ~(1<<CS20);
  TCCR2B &= ~(1<<CS22); //Clearing only this gives best timing.
  
  TIMSK2 |= (1<<TOIE2);
}

And the ISR itself (plus the modified shiftOut() command, it directly accesses the ports to speed up the code greatly):

ISR(TIMER2_OVF_vect) {
  /* Reload the timer */
  TCNT2 = 148; //This seems to not flicker very much. 205 for 4 LEDS, 148 for for 8 LEDS (Must shift out 3 bytes)
  while(ledNumber <= __numLedsInArray-1)
  {
    while(loopCount<=2)
    {
      if(ledStates[ledNumber][loopCount] <= isrCount)
      {
        currBuffer |= (1<<loopCount+(ledNumber*3));
      }
      else
      {
        currBuffer &= ~(1<<loopCount+(ledNumber*3));
      }
      
      loopCount++;
    }
    loopCount=0;
    ledNumber++;
  }
  ledNumber=0;

  //digitalWrite(__latchPin, LOW);
  PORTB &= ~(1<<3);
  shiftOutDedicated((byte)currBuffer);
  shiftOutDedicated((byte)(currBuffer>>8));
  shiftOutDedicated((byte)(currBuffer>>16));
  //digitalWrite(__latchPin, HIGH);
  PORTB |= (1<<3);
  isrCount++;
  
  if(isrCount >= 100)
  {
    isrCount=0;
  }
  
}

void shiftOutDedicated(byte val)
{
      for (int i = 0; i < 8; i++)  {
          if(!!(val & (1<<i)))
          {
            PORTB |= (1<<1); //Set the dataPin bit
          }
          else
          {
            PORTB &= ~(1<<1); //Clear the dataPin bit
          }
         //digitalWrite(dataPin, !!(val & (1 << i)));
          PORTB |= (1<<2); //Clock pin high
          PORTB &= ~(1<<2); //Clear clock pin to low
            //digitalWrite(clockPin, HIGH);
            //digitalWrite(clockPin, LOW);            
  }
}