Blink RGB with millis()

Hi guys

I`m having little issue with the RGB led blink using millis();

I do get some blink but the on/off intervals are not equall.

Section with issue:

    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      setColor(255, 255, 255);
      previousMillis = currentMillis;
    }
    else  {
      setColor(0, ChangeColour, ChangeColour);
    }

Full Code:

int encoderStartValue = 65000;
int inPin = 4;
int ButtonState = 0;
int dacValue = 0;
bool flag = false;
int yPos = 0;

int Rpin = 9;
int Gpin = 10;
int Bpin = 11;

int ChangeColour = 0;

unsigned long previousMillis = 0;
const long interval = 1000;
int ledState = LOW;

#define encoder0PinA  2
#define encoder0PinB  3
#include <Wire.h>
#include "U8glib.h"
#define MCP4725_ADDR 0x60
volatile unsigned int encoder0Pos = encoderStartValue;

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_NO_ACK | U8G_I2C_OPT_FAST); // Fast I2C / TWI

void draw(void) {
  // graphic commands to redraw the complete screen should be placed here
  u8g.setFont(u8g_font_helvB14);
  //u8g.setFont(u8g_font_helvB12);
  u8g.drawStr( 0, 14, "FLAG = ");
  u8g.setPrintPos(74, 14);
  u8g.print(flag);
  u8g.setFont(u8g_font_helvB14);
  u8g.drawStr( 0, 40, "DAC = ");
  u8g.setPrintPos(62, 40);
  u8g.print(dacValue);
  u8g.drawStr( yPos, 61, "BalfourBeatty");
}

void setColor(int Rval, int Gval, int Bval) {
  analogWrite(Rpin, Rval);
  analogWrite(Gpin, Gval);
  analogWrite(Bpin, Bval);
}


void setup() {
  // flip screen, if required
  // u8g.setRot180();
  pinMode(Rpin, OUTPUT);
  pinMode(Gpin, OUTPUT);
  pinMode(Bpin, OUTPUT);
  pinMode(inPin, INPUT);
  pinMode(13, OUTPUT);
  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);
  pinMode(7, OUTPUT);
  digitalWrite(7, LOW);
  pinMode(encoder0PinA, INPUT);
  digitalWrite(encoder0PinA, HIGH);       // turn on pull-up resistor
  pinMode(encoder0PinB, INPUT);
  digitalWrite(encoder0PinB, HIGH);       // turn on pull-up resistor

  attachInterrupt(0, doEncoder, CHANGE);  // encoder pin on interrupt 0 - pin 2
  // Serial.begin (9600);
  Serial.println("start");                // a personal quirk
  Wire.begin();
  setColor(255, 0, 255);
}

void loop() {
  //setColor();
  // picture loop
  u8g.firstPage();
  do {
    draw();
  } while ( u8g.nextPage() );

  // If its too fast, you could add a delay
  if (yPos < 255) {
    // if it's too slow, you could increment y by a greater number
    yPos++;
  }
  else {
    // When the yPos is off the screen, reset to 0.
    yPos = 0;
  }

  ButtonState = digitalRead(inPin);     // read the input pin
  digitalWrite(13, flag);
  // Serial.println(flag);

  // do some stuff here - the joy of interrupts is that they take care of themselves
  if (ButtonState == HIGH )  {
    encoder0Pos = encoderStartValue;
    flag = !flag;
    delay(200);
  }
  if (flag == true) {
    digitalWrite(5, HIGH);
    delay(10);
    digitalWrite(7, HIGH);

    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      setColor(255, 255, 255);
      previousMillis = currentMillis;
    }
    else  {
      setColor(0, ChangeColour, ChangeColour);
    }
  }


  if (flag == false) {
    setColor(255, 0, 255);
    digitalWrite(7, LOW);
    delay(10);
    digitalWrite(5, LOW);
  }

  dacValue = map(encoder0Pos, 0 , 65000, 0, 4096);
  ChangeColour = map(dacValue, 0, 4096, 255, 0);
  Wire.beginTransmission(MCP4725_ADDR);
  Wire.write(64);                     // cmd to update the DAC
  Wire.write(dacValue >> 4);        // the 8 most significant bits...
  Wire.write(dacValue << 4); // the 4 least significant bits...
  Wire.endTransmission();
}


void doEncoder() {

  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB) && (encoder0Pos < 65000)) {
    encoder0Pos += 1000;
  }

  if (digitalRead(encoder0PinA) != digitalRead(encoder0PinB) && (encoder0Pos > 1000)) {
    encoder0Pos -= 1000;
  }


  //Serial.print(encoder0Pos);
  Serial.print (dacValue);
  Serial.print (" flag = ");
  Serial.println (flag);
}

void doEncoder_Expanded() {
  if (digitalRead(encoder0PinA) == HIGH) {   // found a low-to-high on channel A
    if (digitalRead(encoder0PinB) == LOW) {  // check channel B to see which way
      // encoder is turning
      encoder0Pos = encoder0Pos - 1;         // CCW
    }
    else {
      encoder0Pos = encoder0Pos + 1;         // CW
    }
  }
  else                                        // found a high-to-low on channel A
  {
    if (digitalRead(encoder0PinB) == LOW) {   // check channel B to see which way
      // encoder is turning
      encoder0Pos = encoder0Pos + 1;          // CW
    }
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
    }

  }
}

Any help greatly appreciated.
Thanks

how about

if (currentMillis - previousMillis >= interval) {
      setColor(255, 255, 255);
      
    }
    else if (currentMillis - previousMillis >= (interval*2)) {
      setColor(0, ChangeColour, ChangeColour);
      previousMillis = currentMillis;
    }

Deva_Rishi:
how about

if (currentMillis - previousMillis >= interval) {

setColor(255, 255, 255);
     
    }
    else if (currentMillis - previousMillis >= (interval*2)) {
      setColor(0, ChangeColour, ChangeColour);
      previousMillis = currentMillis;
    }

Well, all goes dark with this.

do you still have the unsigned long currentMillis = millis();above that ?

Hi Deva

Just sorted this way:

 int colorFlag = 0;   
unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {

      previousMillis = currentMillis;
      if (colorFlag == 0) {
        colorFlag = 1;
      } else {
        colorFlag = 0;
      }
      if (colorFlag == 1) {
        setColor(255, 255, 255);
      }
      else if (colorFlag == 0) {
        setColor(0, ChangeColor, ChangeColor);
      }
    }

Thanks for your input.