A place users can post their projects. If you have a small project and would like your own dedicated place to post and have others chat about it then this is your spot.

User avatar
By UsernamePersonThingy
#75376 Hi everyone. After some researching and asking some questions online, I have came up with a way to handle smooth fading with the lights. I can confirm that it works perfectly and will smoothly change between colours and fade in and out. It works exactly the same just feels better and smoother to use. I have had to make some slight adjustments to rest of the code to make sure this works best. Feel free to improve the feature. Here is the code:
Code: Select all//NodeMCU RGB-Controller for Homebridge & HomeKit (Siri)

#include <ESP8266WiFi.h>

#define redPin 13 //D7 - Red channel
#define grnPin 12 //D6 - Green channel
#define bluPin 14 //D5 - Blue channel

#define max(a,b) ((a)>(b)?(a):(b))

WiFiServer server(80); //Set server port

String readString;           //String to hold incoming request
String hexString = "FFFFFF"; //Define inititial color here (hex value), 080100 would be a calm warmtone i.e.

int state;

int r;
int g;
int b;

float R;
float G;
float B;

int x;
int V;

///// WiFi SETTINGS - Replace with your values /////////////////
const char* ssid = "x-x-x-x-x";
const char* password = "x-x-x-x-x";
IPAddress ip(x,x,x,x);      // set a fixed IP for the NodeMCU
IPAddress gateway(x,x,x,x);  // Your router IP
IPAddress subnet(255,255,255,0); // Subnet mask
////////////////////////////////////////////////////////////////////

void WiFiStart() {
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  WiFi.config(ip, gateway, subnet); //Set a fixed IP. You can comment this out and set it in your router instead.
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print("_");
  }
  Serial.println();
  Serial.println("Done");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("");

  server.begin();                   
}

void allOff() {
  state = 0;
  for (float fade = 1.0; fade >= 0.0; fade -= 0.01) {
    analogWrite(redPin, map((r * fade), 0, 255, 0, 1023));
    analogWrite(grnPin, map((g * fade), 0, 255, 0, 1023));
    analogWrite(bluPin, map((b * fade), 0, 255, 0, 1023));
    delay(2);
  }
  // Set r/g/b to 0 so fade in is possible
  r = 0;
  b = 0;
  g = 0;
}

//Write requested hex-color to the pins
void setHex() {
  const float STEPS = 100; // Change number of steps while fading (lower is faster)
  // Save old values of r/g/b
  byte oldR = r;
  byte oldG = g;
  byte oldB = b;
  long number = (long) strtol( &hexString[0], NULL, 16);
  r = number >> 16;
  g = number >> 8 & 0xFF;
  b = number & 0xFF;
  float deltaR = (r - oldR) / STEPS;
  float deltaG = (g - oldG) / STEPS;
  float deltaB = (b - oldB) / STEPS;
  // Fade to new colour
  for (float f = 0; f < STEPS; f++) {
    analogWrite(redPin, map((oldR + (deltaR * f)), 0, 255, 0, 1023));
    analogWrite(grnPin, map((oldG + (deltaG * f)), 0, 255, 0, 1023));
    analogWrite(bluPin, map((oldB + (deltaB * f)), 0, 255, 0, 1023));
    delay(2);
  }
  state = 1;
}

//Compute current brightness value
void getV() {
  R = roundf(r/2.55);  //was (r/10.23);
  G = roundf(g/2.55);  //was (g/10.23);
  B = roundf(b/2.55);  //was (b/10.23);
  x = max(R,G);
  V = max(x, B);
}

//For serial debugging only
void showValues() {
  Serial.print("Status on/off: ");
  Serial.println(state);
  Serial.print("RGB color: ");
  Serial.print(r);
  Serial.print(".");
  Serial.print(g);
  Serial.print(".");
  Serial.println(b);
  Serial.print("Hex color: ");
  Serial.println(hexString);
  getV();
  Serial.print("Brightness: ");
  Serial.println(V);
  Serial.println("");
}

void setup(){
  Serial.begin(9600);
  delay(1);
  pinMode(redPin, OUTPUT);  //declaration added
  pinMode(grnPin, OUTPUT);  //declaration added
  pinMode(bluPin, OUTPUT);  //declaration added
  WiFi.mode(WIFI_STA);
  WiFiStart();
  setHex(); //Set initial color after booting. Value defined above
}

void loop() {
  //Reconnect on lost WiFi connection (superfluous - will reconnect anyway)
  /*if (WiFi.status() != WL_CONNECTED) {
    WiFiStart();
  }
  */ 

  WiFiClient client = server.available();
 
  if (!client) {
    return;
  }
 
  while(client.connected() && !client.available()) {
    delay(1);
  }
   
  //Respond on certain Homebridge HTTP requests
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (readString.length() < 100) {
          readString += c;
        }
        if (c == '\n') {
          //Serial.print("Request: ");
          //Serial.println(readString);
         
          //Send reponse
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
         
          //On
          if(readString.indexOf("on") >0) {
            setHex();
            //showValues();
          }
     
          //Off
          if(readString.indexOf("off") >0) {
            allOff();
            //showValues();
          }

          //Set color
          if(readString.indexOf("set") >0) {
            hexString = "";
            hexString = (readString.substring(9,15));
            setHex();
            //showValues();
          }
         
          //Status on/off
          if(readString.indexOf("status") >0) {
          client.println(state);
          }

          //Status color (hex)
          if(readString.indexOf("color") >0) {
          client.println(hexString);
          }

          //Status brightness (%)
          if(readString.indexOf("bright") >0) {
          getV();
          client.println(V);
          }
         
          delay(1);
          client.stop();
          readString="";
        }
      }
    }
  }
}

Thank you and have a good day. :D
User avatar
By Raptoaaah
#75922 Hey everyone,
today I experienced the same ECONNRESET-bug as mentioned before. This seemingly is related to the 2.0-update of the homebridge-plugin which improved error-handling and communication protocols and therefore does not affect those who have older versions. Don't worry, I got it fixed today for the newer version ;). The error can be resolved by inserting
Code: Select allwhile (client.read() >= 0);
right before
Code: Select allclient.stop();
. As the previous code just cuts the communication (thats where the ECONNRESET comes from) without reading the remaining buffer, homebridge sees unsent packages and a broken channel. This is solvable by simply emptying the buffer and close it afterwards (as there is no other useful information in the communication).