Neopixel Ring - How to breathe in a circle

I'm trying to get an effect like (Vine). The code I have right now can make the leds turn on and off in a circle but it's too abrupt. Any help would be very much appreciated!

#include <Adafruit_NeoPixel.h>          // Library for NeoPixels

#define pinPix 6                       // Pin driving NeoPixel Ring or String
#define numPix 8                       // Number of NeoPixels in the Ring or Strip

// Setup NeoPixel Ring
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number driving the strip
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel myNeoPixels = Adafruit_NeoPixel(numPix, pinPix, NEO_GRB + NEO_KHZ800);


void setup() {
  myNeoPixels.begin();   // Initialize the NeoPixel array in the Arduino's memory,
  myNeoPixels.show();    // turn all pixels off, and upload to ring or string

}

void loop() {
  ledTrail(100, 255,255,255, 0,0,0);       // Pause; R,G,B foreground; R,G,B background
}


// Pause = delay between transitions
// Rf, Gf, Bf = RGB "Foreground" values
// Rb, Gb, Bb = RGB "Background" values
void ledTrail(int pause, byte Rf, byte Gf, byte Bf, byte Rb, byte Gb, byte Bb) { 

  for (int i=0; i<numPix; i++) {
    myNeoPixels.setPixelColor(i,Rf,Gf,Bf);
    myNeoPixels.show();
    delay(pause);
  }

  for (int i=0; i<numPix; i++) {
    myNeoPixels.setPixelColor(i,Rb,Gb,Bb);
    myNeoPixels.show();
    delay(pause);
  }
}

but it's too abrupt.

This suggests that the time spent in any one position is too short, so increasing the delay value is in order.

If that is not the solution, you need to describe what "too abrupt" means.

PaulS:
This suggests that the time spent in any one position is too short, so increasing the delay value is in order.

If that is not the solution, you need to describe what "too abrupt" means.

Ah sorry. By abrupt I meant that the LEDs simply turn on and off but don't fade on and off.

By abrupt I meant that the LEDs simply turn on and off but don't fade on and off.

That's what you tell them to do.

You need to call letsDoIt() (stupid name; no one can guess what that function is supposed to do!) with something other than constant arguments.

PaulS:
That's what you tell them to do.

You need to call letsDoIt() (stupid name; no one can guess what that function is supposed to do!) with something other than constant arguments.

Sorry I changed its name to ledTrail, hopefully that makes more sense. Anyways, I can make the LEDs breathe all at once but I can't get a combination of the two codes to work like in the GIF. I'm basically stuck trying to put the following breathe code into the trailing LED code in the OP.

#include <Adafruit_NeoPixel.h>          // Library for NeoPixels

#define pinPix 6                       // Pin driving NeoPixel Ring or String
#define numPix 8                       // Number of NeoPixels in the Ring or Strip

// Setup NeoPixel Ring
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number driving the strip
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel myNeoPixels = Adafruit_NeoPixel(numPix, pinPix, NEO_GRB + NEO_KHZ800);


void setup() {
  myNeoPixels.begin();   // Initialize the NeoPixel array in the Arduino's memory,
  myNeoPixels.show();    // turn all pixels off, and upload to ring or string

}

void loop() {
  breathe(20, 100, 255,255,255);       // Pause; Number of steps; Full-on R,G,B values
}


// Pause = delay between transitions
// Steps = number of steps
// R, G, B = Full-on RGB values
void breathe(int pause, int steps, byte R, byte G, byte B) { 

  int tmpR, tmpG, tmpB;         // Temp values
  
  // Fade up
  for (int s=1; s<=steps; s++) {
    tmpR = (R * s) / steps;     // Multiply first to avoid truncation errors  
    tmpG = (G * s) / steps;
    tmpB = (B * s) / steps;
    
    for (int i=0; i<numPix; i++) {
      myNeoPixels.setPixelColor(i,tmpR,tmpG,tmpB);
    }
    myNeoPixels.show();
    delay(pause);
  }    

  // Fade down
  for (int s=steps; s>0; s--) {
    tmpR = (R * s) / steps;     // Multiply first to avoid truncation errors  
    tmpG = (G * s) / steps;
    tmpB = (B * s) / steps;
    
    for (int i=0; i<numPix; i++) {
      myNeoPixels.setPixelColor(i,tmpR,tmpG,tmpB);
    }
    myNeoPixels.show();
    delay(pause);
  }    

  delay(pause * 30);
}

I have done something like this as follows:

define the leds that you want to breathe in an array like these:

const uint8_t sunshine_Weather[] = {137,138,139,140};
const uint8_t partlyCloudy_Weather[] = {133,134,135,136};
const uint8_t overcast_Weather[] = {129,130,131,132};
const uint8_t lightning_Weather[] = {125,126,127,128};
const uint8_t rain_Weather[] = {121,122,123,124};
const uint8_t snow_Weather[] = {117,118,119,120};

call a function in loop() (I did in a switch/case based on a state) like this:

switch (weather_State){
          case (SUNSHINE):
            breatheUpdate(sunshine_Weather, sizeof(sunshine_Weather), BREATH_RATE, 1);
            break;
          case (SNOW):
            breatheUpdate(snow_Weather, sizeof(snow_Weather), BREATH_RATE, 1);
            break;
          case (PARTLY_CLOUDY):
            breatheUpdate(partlyCloudy_Weather, sizeof(partlyCloudy_Weather), BREATH_RATE, 1);
            break;
          case (OVERCAST):
            breatheUpdate(overcast_Weather, sizeof(overcast_Weather), BREATH_RATE, 1);
            break;
          case (LIGHTNING):
            breatheUpdate(lightning_Weather, sizeof(lightning_Weather), BREATH_RATE, 1);
            break;
          case (RAIN):
            breatheUpdate(rain_Weather, sizeof(rain_Weather), BREATH_RATE, 1);
            break;
        }

and the function looks like this:

void breatheUpdate(const uint8_t * segment, const uint8_t numLeds, const uint32_t increment, const uint8_t step)
{
  static uint32_t lastTimeChange = 0;
  static uint8_t direction = 1;
  const static uint8_t lowLimit = 50;
  static uint8_t value = lowLimit;
  if(millis() - lastTimeChange > increment)
  {
    value +=(direction * step);
    value = constrain(value, lowLimit, 255);
    if (value <= lowLimit || value >= 255)
    {
      direction = direction * -1;
    }
    for(uint8_t i = 0; i < numLeds; i++)  
    {
      myPixels.setPixelColor(segment[i], myPixels.Color(0, 0, value));
      if (value > lowLimit + 5 && value < lowLimit + 10 && weather_State == LIGHTNING) // you don't need this block.... I use it for lightning effect!
      {
        myPixels.setPixelColor(127, myPixels.Color(255, 255, 255));
      }
    }
    myPixels.show();
    lastTimeChange += increment;
  }
}

and

#define BREATH_RATE 10UL