diff --git a/PowerRGB_master.ino b/PowerRGB_master.ino new file mode 100644 index 0000000..36c707d --- /dev/null +++ b/PowerRGB_master.ino @@ -0,0 +1,495 @@ +#include +#include +#include +#include +#include + +const int redPin = 12; // Red +const int greenPin = 13; // Green +const int bluePin = 14; // Blue + +const int warning = 16; +const int pwmResolution = 1024; + +TwoWire Wire_; + +// INA226 instances +INA226 redINA(0x45, &Wire_); // 1000101 +INA226 blueINA(0x41, &Wire_); // 1000100 +INA226 greenINA(0x44, &Wire_); // 1000001 + +const char *ssid = "dlink-AB48"; +const char *password = "mjjbk74568"; + +// Array to store slave IP addresses +const char* slaveIPs[] = { + "192.168.129.119", // Slave 1 +}; +const int NUM_SLAVES = sizeof(slaveIPs) / sizeof(slaveIPs[0]); + +int redValue = 0; +int greenValue = 0; +int blueValue = 0; +float brightness = 100.0; +bool rainbowActive = false; +unsigned long lastRainbowUpdate = 0; +int currentHue = 0; + +// New variables for current monitoring +float redCurrent = 0; +float greenCurrent = 0; +float blueCurrent = 0; +unsigned long lastCurrentUpdate = 0; + +ESP8266WebServer server(80); +WiFiClient wifiClient; + + +void handleSetRGB() { + if (server.hasArg("r") && server.hasArg("g") && server.hasArg("b")) { + redValue = server.arg("r").toInt(); + greenValue = server.arg("g").toInt(); + blueValue = server.arg("b").toInt(); + rainbowActive = false; + + // Set master LED + setRGB(redValue, greenValue, blueValue, brightness); + + // Propagate to slaves + String url = String("/set_rgb?r=") + redValue + + String("&g=") + greenValue + + String("&b=") + blueValue; + propagateToSlaves(url); + + server.send(200, "text/plain", "RGB updated"); + } else { + server.send(400, "text/plain", "Missing RGB arguments"); + } +} + + +// Modified handleSetBrightness to propagate to slaves +void handleSetBrightness() { + if (server.hasArg("value")) { + brightness = server.arg("value").toFloat(); + setRGB(redValue, greenValue, blueValue, brightness); + + // Propagate to slaves + String url = String("/set_brightness?value=") + brightness; + propagateToSlaves(url); + + server.send(200, "text/plain", "Brightness updated"); + } else { + server.send(400, "text/plain", "Missing brightness argument"); + } +} + +// Modified handleRainbow to propagate to slaves +void handleRainbow() { + if (server.hasArg("state")) { + rainbowActive = server.arg("state") == "true"; + if (!rainbowActive) { + setRGB(redValue, greenValue, blueValue, brightness); + } + + // Propagate to slaves + String url = String("/rainbow?state=") + server.arg("state"); + propagateToSlaves(url); + } + server.send(200, "text/plain", rainbowActive ? "Rainbow started" : "Rainbow stopped"); +} + +// New function to propagate commands to slaves +void propagateToSlaves(String endpoint) { + HTTPClient http; + for (int i = 0; i < NUM_SLAVES; i++) { + String url = String("http://") + slaveIPs[i] + endpoint; + http.begin(wifiClient, url); + int httpCode = http.GET(); + + if (httpCode != HTTP_CODE_OK) { + Serial.printf("Failed to propagate to slave %s: %d\n", slaveIPs[i], httpCode); + } + http.end(); + } +} + +void handleGetCurrents() { + String json = "{\"red\":" + String(redCurrent, 3) + + ",\"green\":" + String(greenCurrent, 3) + + ",\"blue\":" + String(blueCurrent, 3) + + ",\"total\":" + String(redCurrent + greenCurrent + blueCurrent, 3) + + ",\"redBusV\":" + String(redINA.getBusVoltage(), 3) + + ",\"greenBusV\":" + String(greenINA.getBusVoltage(), 3) + + ",\"blueBusV\":" + String(blueINA.getBusVoltage(), 3) + + "}"; + server.send(200, "application/json", json); +} + +void scanI2CBus(TwoWire &wire) { + Serial.println("Scanning I2C Bus..."); + for (uint8_t address = 1; address < 127; ++address) { + wire.beginTransmission(address); + if (wire.endTransmission() == 0) { + Serial.print("Device found at address 0x"); + Serial.println(address, HEX); + } + } +} + +void initializeINA226(INA226 &sensor, const char* name) { + if (!sensor.begin()) { + Serial.print("INA226 initialization failed for "); + Serial.println(name); + } else { + Serial.print("INA226 initialized for "); + Serial.println(name); + } + + if (strcmp(name, "RED") == 0) { + sensor.setMaxCurrentShunt(0.4, 0.09); + } else if (strcmp(name, "GREEN") == 0) { + sensor.setMaxCurrentShunt(0.35, 0.18); + } else if (strcmp(name, "BLUE") == 0) { + sensor.setMaxCurrentShunt(0.35, 0.18); + } else { + // Default case for unknown names + sensor.setMaxCurrentShunt(0, 0); + } +} + + +void setup() { + Serial.begin(115200); + analogWriteRange(pwmResolution); + Serial.println("Initializing RGB LED Controller with Current Monitoring"); + + + pinMode(redPin, OUTPUT); + pinMode(greenPin, OUTPUT); + pinMode(bluePin, OUTPUT); + setRGB(redValue, greenValue, blueValue, brightness); + + delay(100); + Wire_.begin(5, 4); + delay(200); + scanI2CBus(Wire_); + delay(200); // Extended delay + initializeINA226(redINA, "RED"); + delay(200); + initializeINA226(greenINA, "GREEN"); + delay(200); + initializeINA226(blueINA, "BLUE"); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(1000); + Serial.print("."); + } + Serial.println("Connected to Wi-Fi"); + Serial.print("IP Address: "); + Serial.println(WiFi.localIP()); + + server.on("/", handleRoot); + server.on("/set_rgb", handleSetRGB); + server.on("/set_brightness", handleSetBrightness); + server.on("/rainbow", handleRainbow); + server.on("/get_currents", handleGetCurrents); + + server.begin(); +} + +void loop() { + server.handleClient(); + + unsigned long currentMillis = millis(); + + // Current measurement update (every 100ms) + if (currentMillis - lastCurrentUpdate >= 100) { + // Get current readings from all sensors + redCurrent = redINA.getCurrent_mA(); + greenCurrent = greenINA.getCurrent_mA(); + blueCurrent = blueINA.getCurrent_mA(); + lastCurrentUpdate = currentMillis; + } + + // Rainbow animation update (every 20ms) + if (rainbowActive && (currentMillis - lastRainbowUpdate >= 20)) { + float r, g, b; + hsvToRgb(currentHue, 1.0, brightness / 100.0, r, g, b); + setRGB((int)(r * 255), (int)(g * 255), (int)(b * 255), brightness); + currentHue = (currentHue + 1) % 360; + lastRainbowUpdate = currentMillis; + } +} + +void hsvToRgb(int hue, float saturation, float value, float &r, float &g, float &b) { + float c = value * saturation; + float x = c * (1 - abs(fmod(hue / 60.0, 2) - 1)); + float m = value - c; + + if (hue >= 0 && hue < 60) { + r = c; g = x; b = 0; + } else if (hue >= 60 && hue < 120) { + r = x; g = c; b = 0; + } else if (hue >= 120 && hue < 180) { + r = 0; g = c; b = x; + } else if (hue >= 180 && hue < 240) { + r = 0; g = x; b = c; + } else if (hue >= 240 && hue < 300) { + r = x; g = 0; b = c; + } else { + r = c; g = 0; b = x; + } + + r += m; g += m; b += m; +} + +int mapDutyCycle(int value, float brightness) { + float adjusted = value * (brightness / 100.0); + return (int)(adjusted * pwmResolution / 255.0); +} + +void setRGB(int red, int green, int blue, float brightness) { + analogWrite(redPin, mapDutyCycle(red, brightness)); + analogWrite(greenPin, mapDutyCycle(green, brightness)); + analogWrite(bluePin, mapDutyCycle(blue, brightness)); +} + +#include +#include + +// [Previous ESP8266 setup code remains the same until handleRoot()] + +void handleRoot() { + String html = R"rawliteral( + + + + RGB Control + + + + + +
+ + + + )rawliteral"; + + server.send(200, "text/html", html); +} \ No newline at end of file diff --git a/PowerRGB_standalone.ino b/PowerRGB_standalone.ino new file mode 100644 index 0000000..fc927f1 --- /dev/null +++ b/PowerRGB_standalone.ino @@ -0,0 +1,453 @@ +#include +#include +#include +#include + + +const int redPin = 12; // Red +const int greenPin = 13; // Green +const int bluePin = 14; // Blue + +const int warning = 16; +const int pwmResolution = 1024; + +TwoWire Wire_; + +// WiFi Configuration +const char *ap_ssid = "RGB_Controller"; // Name of the WiFi network to create +const char *ap_password = "12345678"; // Password for the WiFi network +IPAddress local_ip(192,168,4,1); // Static IP address for the access point +IPAddress gateway(192,168,4,1); // Gateway (same as static IP) +IPAddress subnet(255,255,255,0); // Subnet mask + +// INA226 instances +INA226 redINA(0x45, &Wire_); // 1000101 +INA226 blueINA(0x41, &Wire_); // 1000100 +INA226 greenINA(0x44, &Wire_); // 1000001 + + +ESP8266WebServer server(80); + +int redValue = 0; +int greenValue = 0; +int blueValue = 0; +float brightness = 100.0; +bool rainbowActive = false; +unsigned long lastRainbowUpdate = 0; +int currentHue = 0; + +// New variables for current monitoring +float redCurrent = 0; +float greenCurrent = 0; +float blueCurrent = 0; +unsigned long lastCurrentUpdate = 0; + +void handleSetRGB() { + if (server.hasArg("r") && server.hasArg("g") && server.hasArg("b")) { + redValue = server.arg("r").toInt(); + greenValue = server.arg("g").toInt(); + blueValue = server.arg("b").toInt(); + rainbowActive = false; // Stop rainbow when setting manual color + setRGB(redValue, greenValue, blueValue, brightness); + server.send(200, "text/plain", "RGB updated"); + } else { + server.send(400, "text/plain", "Missing RGB arguments"); + } + delay(10); +} + +void handleSetBrightness() { + if (server.hasArg("value")) { + brightness = server.arg("value").toFloat(); + setRGB(redValue, greenValue, blueValue, brightness); + server.send(200, "text/plain", "Brightness updated"); + } else { + server.send(400, "text/plain", "Missing brightness argument"); + } +} + +void handleRainbow() { + if (server.hasArg("state")) { + rainbowActive = server.arg("state") == "true"; + if (!rainbowActive) { + // Restore the last manual color when rainbow is turned off + setRGB(redValue, greenValue, blueValue, brightness); + } + } + server.send(200, "text/plain", rainbowActive ? "Rainbow started" : "Rainbow stopped"); +} + + +void handleGetCurrents() { + String json = "{\"red\":" + String(redCurrent, 3) + + ",\"green\":" + String(greenCurrent, 3) + + ",\"blue\":" + String(blueCurrent, 3) + + ",\"total\":" + String(redCurrent + greenCurrent + blueCurrent, 3) + + ",\"redBusV\":" + String(redINA.getBusVoltage(), 3) + + ",\"greenBusV\":" + String(greenINA.getBusVoltage(), 3) + + ",\"blueBusV\":" + String(blueINA.getBusVoltage(), 3) + + "}"; + server.send(200, "application/json", json); +} + +void scanI2CBus(TwoWire &wire) { + Serial.println("Scanning I2C Bus..."); + for (uint8_t address = 1; address < 127; ++address) { + wire.beginTransmission(address); + if (wire.endTransmission() == 0) { + Serial.print("Device found at address 0x"); + Serial.println(address, HEX); + } + } +} + +void initializeINA226(INA226 &sensor, const char* name) { + if (!sensor.begin()) { + Serial.print("INA226 initialization failed for "); + Serial.println(name); + } else { + Serial.print("INA226 initialized for "); + Serial.println(name); + } + + if (strcmp(name, "RED") == 0) { + sensor.setMaxCurrentShunt(0.4, 0.09); + } else if (strcmp(name, "GREEN") == 0) { + sensor.setMaxCurrentShunt(0.35, 0.18); + } else if (strcmp(name, "BLUE") == 0) { + sensor.setMaxCurrentShunt(0.35, 0.18); + } else { + // Default case for unknown names + sensor.setMaxCurrentShunt(0, 0); + } +} + + +void setup() { + Serial.begin(115200); + analogWriteRange(pwmResolution); + Serial.println("Initializing RGB LED Controller with Current Monitoring"); + + pinMode(redPin, OUTPUT); + pinMode(greenPin, OUTPUT); + pinMode(bluePin, OUTPUT); + setRGB(redValue, greenValue, blueValue, brightness); + + // Initialize I2C and INA226 sensors + delay(100); + Wire_.begin(5, 4); + delay(200); + scanI2CBus(Wire_); + delay(200); + initializeINA226(redINA, "RED"); + delay(200); + initializeINA226(greenINA, "GREEN"); + delay(200); + initializeINA226(blueINA, "BLUE"); + + // Configure ESP8266 as Access Point + WiFi.mode(WIFI_AP); + WiFi.softAPConfig(local_ip, gateway, subnet); + WiFi.softAP(ap_ssid, ap_password); + + Serial.println("WiFi Access Point Created"); + Serial.print("SSID: "); + Serial.println(ap_ssid); + Serial.print("Password: "); + Serial.println(ap_password); + Serial.print("IP Address: "); + Serial.println(local_ip); + + server.on("/", handleRoot); + server.on("/set_rgb", handleSetRGB); + server.on("/set_brightness", handleSetBrightness); + server.on("/rainbow", handleRainbow); + server.on("/get_currents", handleGetCurrents); + + server.begin(); + Serial.println("HTTP server started"); +} + +void loop() { + server.handleClient(); + + unsigned long currentMillis = millis(); + + // Current measurement update (every 100ms) + if (currentMillis - lastCurrentUpdate >= 100) { + // Get current readings from all sensors + redCurrent = redINA.getCurrent_mA(); + greenCurrent = greenINA.getCurrent_mA(); + blueCurrent = blueINA.getCurrent_mA(); + lastCurrentUpdate = currentMillis; + } + + // Rainbow animation update (every 20ms) + if (rainbowActive && (currentMillis - lastRainbowUpdate >= 20)) { + float r, g, b; + hsvToRgb(currentHue, 1.0, brightness / 100.0, r, g, b); + setRGB((int)(r * 255), (int)(g * 255), (int)(b * 255), brightness); + currentHue = (currentHue + 1) % 360; + lastRainbowUpdate = currentMillis; + } +} + +void hsvToRgb(int hue, float saturation, float value, float &r, float &g, float &b) { + float c = value * saturation; + float x = c * (1 - abs(fmod(hue / 60.0, 2) - 1)); + float m = value - c; + + if (hue >= 0 && hue < 60) { + r = c; g = x; b = 0; + } else if (hue >= 60 && hue < 120) { + r = x; g = c; b = 0; + } else if (hue >= 120 && hue < 180) { + r = 0; g = c; b = x; + } else if (hue >= 180 && hue < 240) { + r = 0; g = x; b = c; + } else if (hue >= 240 && hue < 300) { + r = x; g = 0; b = c; + } else { + r = c; g = 0; b = x; + } + + r += m; g += m; b += m; +} + +int mapDutyCycle(int value, float brightness) { + float adjusted = value * (brightness / 100.0); + return (int)(adjusted * pwmResolution / 255.0); +} + +void setRGB(int red, int green, int blue, float brightness) { + analogWrite(redPin, mapDutyCycle(red, brightness)); + analogWrite(greenPin, mapDutyCycle(green, brightness)); + analogWrite(bluePin, mapDutyCycle(blue, brightness)); +} + +#include +#include + +// [Previous ESP8266 setup code remains the same until handleRoot()] + +void handleRoot() { + String html = R"rawliteral( + + + + RGB Control + + + + +
+
+

RGB Control

+
+ +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+ + + 100% +
+ +
+ +
+
+ +
+

Current Monitor

+
+
+ Red LED: + 0.00 mA +
+
+ Green LED: + 0.00 mA +
+
+ Blue LED: + 0.00 mA +
+
+ Total Current: + 0.00 mA +
+
+
+
+ + + + +)rawliteral"; + + server.send(200, "text/html", html); +}