Heavy current, dimming room lights with multiple control systems

I have written up my project at:

https://cabin-layout.mixmox.com/2019/01/room-lighting-with-remotesign.html

In addition to a Blynk interface I also added direct API calls using my RemoteSign API

where is your sketch ? :wink:

1 Like

well, the code is contained in 7 different files. The library implementing the RemoteSign is published with a sample sketch at:
https://remotesign.mixmox.com/p/esp8266-sample-sketch.html

I do not want to publish the parts that handle OTA updates as it includes the URL structure I use on a public server and the rest is rather plain vanilla stuff.

yes but this place is to share the code, not just the ideas :wink:
we are just happy for you :wink:

1 Like

Ideas are better than nothing, and yes, some code is a bit too proprietary to benefit others without extensive modification, so not worth posting.

But it is nice to see some of the details and pictures actually posted here, instead of just links. That is better for a sense of forum community integration as opposed to just treating this as a redirection bulletin board.

1 Like

well enjoy…

//#include "ESP8266WiFi.h"

#include "RemoteSign.h"
#include "Ceiling.h"
#include "utils.h"  // auth code, wifi password etc...
#include <BlynkSimpleEsp8266.h>
#include "Blynkhelper.h"
#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>
#include "ota.h"

// hardware setup -----------------------------------------------------
// D0 (built-in) used to show RemoteSign connection
const byte WARM = 4; // D2 Ceiling warm whites
const byte COOL = 5; // D1 Ceiling cool whites
const byte MOUNTAINS = 12; // D6
const byte HIDDEN = 13;  // D7
const byte BUTTON = 14; // D5 pushbutton to toggle hidden area
//--------------------------------------------------------------------------
const int DEFAULT_BRI = 800; // 800/1023

RemoteSign rs; //create an instance of RemoteSign
int duration = 0 ; // duration of phone app transitions
int coolBrightness = DEFAULT_BRI; // keep cool brightness value for lightning routine

void BlynkVWriteByte_helper(uint8_t pin, uint8_t value) {
   Blynk.virtualWrite(pin, value);
   if (pin = V2) {coolBrightness = value;} // keep for lightning
}


void BlynkVWriteStr_helper(uint8_t pin, char const *pchar) {
   Blynk.virtualWrite(pin, pchar);  
}

void lightning(){
  Serial.println(F("Lightning"));
     
     int d = random(10,50) ; // delay
     analogWrite(COOL, 1023);
     delay(d);
     analogWrite(COOL, 0);
     delay(d);
     analogWrite(COOL, 1023);
     yield;
     delay(d);
     analogWrite(COOL, 0);
     delay(d);
     analogWrite(COOL, 1023);
     delay(d);
     analogWrite(COOL, map(coolBrightness,0,100,0,1023)); //put old value back
}

void executeEvent(int channel,String param) {
  //Serial.print(F("Execute event: "));Serial.println(channel);
  //Serial.print(F("Params: "));Serial.println(param);
  switch (channel) {
    case 5: {// lightning
     lightning();
     break;
    } // case 5
   default: {
      Serial.print(F("Unhandled event on channel: "));Serial.println(channel);
      return;
    }
  } // switch
} // executeEvent

void displayLabel(int V,int value, int duration){ // V == 0 will do all (for when duration is zero)
  String toUse;
  switch (V) {
    case 0: {
      displayLabel(V1,value,duration); // call ourselves thrice
      displayLabel(V2,value,duration);
      displayLabel(V3,value,duration);
      return;
    }
    case V1 : {if (duration == 0)  {toUse = "Warm";} else{toUse = "Warm -> " + String(value);};    break;    }
    case V2 : {if (duration == 0)  {toUse = "Cool";} else{toUse = "Cool -> " + String(value);};    break;    }
    case V3 : {if (duration == 0)  {toUse = "πŸ”";} else{toUse = "πŸ” -> " + String(value);};    break;    }
  }
  Blynk.setProperty(V, "label", toUse);
}

BLYNK_WRITE(V0) // all on/off button
{   
  int value = (param.asInt() ==0) ? 0 : 100; // Get value as integer
  //Serial.print("V0"); Serial.print(" now "); Serial.println(value);
  rs.LM(1,value,duration);  
  Blynk.virtualWrite(V1,value);
  displayLabel(V1,value,duration);
  rs.LM(2,value,duration);   
  Blynk.virtualWrite(V2,value);
  displayLabel(V2,value,duration);
  rs.LM(3,value,duration);   
  Blynk.virtualWrite(V3,value);
  displayLabel(V3,value,duration);
  
  rs.LM(4,value == 0 ? LOW:HIGH   ,0 );  
  Blynk.virtualWrite(V4,value == 0 ? LOW:HIGH);
}

BLYNK_WRITE(V10) { // duration widget
  duration = param.asInt(); // keep value in global var
  if (duration == 0) {
    displayLabel(duration,duration,duration); //all zero
  }
}

void presets(int preset) // presets
{   
  int value[4]; // 0 to 3
  switch (preset) {
    case 21 : { value[1] = 10; value[2]=10;value[3]=70; break;    } //sunset
    case 22 : { value[1] = 70; value[2]=80;value[3]=0; break;    } //cloudy
    case 23 : { value[1] = 100; value[2]=100;value[3]=0; break;    } // sunny
    case 24 : { value[1] = 0; value[2]=0;value[3]=30; break;    } // night
    case 25 : { value[1] = 0; value[2]=10;value[3]=20; break;    } // moonlight
    case 26 : { value[1] = 100; value[2]=100;value[3]=20; break;    } // all on
    case 27 : { value[1] = 0; value[2]=0;value[3]=0; break;    } // all off
  }  
  rs.LM(1,value[1],duration);  
  rs.LM(2,value[2],duration);  coolBrightness = value[2];
  rs.LM(3,value[3],duration);  
  if (duration==0) {
    Blynk.virtualWrite(V1,value[1]);
    Blynk.virtualWrite(V2,value[2]);
    Blynk.virtualWrite(V3,value[3]);
  }
  displayLabel(V1,value[1],duration);
  displayLabel(V2,value[21],duration);
  displayLabel(V3,value[3],duration);
}

BLYNK_WRITE(V30) { // update button pressed
  if (param.asInt() == 1) {
     Blynk.setProperty(V30,"label",F("Checking"));
    checkForUpdates(); // won't return if there is an update attempt
    showversion(); 
  }
}

BLYNK_WRITE(V31) {    // Network status
  int ask = param.asInt() ; // assigning incoming value 
  if (ask == 1) {
    long rssi = WiFi.RSSI();
    Blynk.setProperty(V31,"offLabel","πŸ“Ά " + String(rssi) + "dBm");
  }
}  // V3

BLYNK_WRITE_DEFAULT() { // V1 - V3 sliders for channels 1 - 3 and V4 button for ch 4
  int pin = request.pin;     
  int value = param.asInt();  
   //Serial.print("V");Serial.print(pin);Serial.print(" now "); Serial.println(value);
   // V pins match the channels in this project
  switch (pin) {
    // light sliders
    case 1 :
    case 2 :
    case 3 : { 
     rs.LM(pin,value,duration); 
     displayLabel(pin,value,duration);
     if (pin = V2) {coolBrightness = map(value,0,100,0,1023);} // keep cool brightness for lightning
     break;
    }
    case 4 : {
      rs.LM(pin,value == 0 ? LOW:HIGH,0); 
      break;
    }
    // presets
    case 21 :
    case 22 :
    case 23 :
    case 24 :
    case 25 :
    case 26 :
    case 27 :
       presets(pin);
       break; 
    // events
    case 40 :  // lightning flash
      lightning();
      break;
     
  } // switch
} // default catch all

void checkButton(){
  static int laststate = HIGH; // pin is using PULLUP
  int state = digitalRead(BUTTON);
  if (state == laststate) { return;} // no change
  // it changed
  if (state==LOW) { // it went LOW indicating it was pressed
    rs.LM(4,-1,0); //  toggle ch 4
  }
  laststate=state;
  
}
void showversion(){
  Blynk.setProperty(V30,"label","Ver " + String(FW_VERSION));
}

void setup() {
  // switch a string of lights to DEFAULT_BRI right away
  pinMode(WARM, OUTPUT); analogWrite(WARM, DEFAULT_BRI);

  //Serial.begin(115200);
  
  // get onto wifi
  // method #1
  //WiFiConnect(ssid, password); // non-Blynk
  // method #2
  //WiFi.begin(ssid, pass);  // Non-blocking if no WiFi available
  //Blynk.config(auth, server, port);
  //Blynk.connect();
  // method #3
   Blynk.begin(auth, ssid, password); // get onto wifi network with Blynk
   printWifiStatus();

  
  // switch second string of lights to DEFAULT_BRI after connecting
  pinMode(COOL, OUTPUT); analogWrite(COOL, DEFAULT_BRI);

  // show version of firmware
  showversion();
  
  
  //   set up pushbutton pin
  pinMode(BUTTON,INPUT_PULLUP); 
  
  // set the app duration slider to zero
  Blynk.virtualWrite(V10,duration);

  // set up RemoteSign
  rs.setFirmwareVersion("Ceiling " + String(FW_VERSION));
  // define channel data
  rs.setChannelData(1, 'M', WARM, true, "warm"); // 3.5 Amps draw
  rs.setChannelData(2, 'M', COOL, true, "cool");  // 5 Amps draw
  rs.setChannelData(3, 'M', MOUNTAINS, true, "mountains"); // 2.7 Amps draw
  rs.setChannelData(4, 'M', HIDDEN, false, "hidden area");  // ~ 3 Amps draw
  rs.setChannelData(5, 'E', "Lightning");
 
  // map virtual pins to channels
  rs.setBlynkPin(1, 1); 
  rs.setBlynkPin(2, 2);
  rs.setBlynkPin(3, 3);
  rs.setBlynkPin(4, 4);
  
  // set some default values
  // todo
  
  rs.begin(); // start server listening
} // setup

void loop() {
  rs.run();
  Blynk.run();
  checkButton();
} // loop()

and utils.h

//utils
#ifndef utils_h
#define utils_h
//#include "ESP8266WiFi.h"

String getMAC() {
  uint8_t mac[6];
  const byte len = 18; //length of MAC address string
  char result[len];
  WiFi.macAddress(mac);
  // I use - instead of : so that the MAC address can be used in URI
  snprintf(result, len, "%02x-%02x-%02x-%02x-%02x-%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  // ucase the hex values
  for(int i = 0; i<len;  i++) {
     result[i] = toupper(result[i]);
   }
  
  return String(result);
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print(F("\n🌐 SSID: "));
  Serial.print(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print(F(" πŸ–§ IP: "));
  Serial.print(ip);

  Serial.print(F(" MAC: "));
  Serial.print(getMAC());

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print(F(" πŸ“Ά "));
  Serial.print(rssi);
  Serial.println(F("dBm"));
}

void WiFiConnect(char const* ssid, char const* password) {
  WiFi.begin(ssid, password);
  Serial.print(ssid);
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    Serial.print(F("⏳"));
  }
  printWifiStatus();
}

#endif  // #ifndef utils
1 Like