R4 wifi controls the color of RGB light by WiFi

#include <WiFiS3.h>
 
// 设置WiFi凭据
const char* ssid = "YourWiFiSSID";
const char* password = "YourWiFiPassword";
 
// 设置RGB引脚
const int redPin = 9;
const int greenPin = 10;
const int bluePin = 11;
 
// 预设颜色 (R, G, B)
const int presetColors[6][3] = {
  {255, 0, 0},     // 红色
  {0, 255, 0},     // 绿色
  {0, 0, 255},     // 蓝色
  {255, 255, 0},   // 黄色
  {255, 0, 255},   // 紫色
  {0, 255, 255}    // 青色
};
 
// 当前颜色和渐变状态
int currentR = 0, currentG = 0, currentB = 0;
bool fading = false;
int fadeSpeed = 50; // 渐变速度(毫秒)
 
WiFiServer server(80);
 
void setup() {
  Serial.begin(9600);
  while (!Serial);
  
  // 设置RGB引脚为输出
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  
  // 初始关闭LED(共阳极)
  setColor(255, 255, 255);
  
  // 连接WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  
  server.begin();
}
 
void loop() {
  handleWebClient();
  
  // 如果正在渐变,执行渐变效果
  if (fading) {
    fadeToRandomColor();
    delay(fadeSpeed);
  }
}
 
void handleWebClient() {
  WiFiClient client = server.available();
  
  if (client) {
    Serial.println("New client connected");
    String currentLine = "";
    String request = "";
    
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        request += c;
        Serial.write(c);
        
        if (c == '\n') {
          if (currentLine.length() == 0) {
            // 发送HTTP响应头
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            
            // 发送HTML页面
            sendControlPage(client);
            
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
        
        // 处理各种请求
        if (currentLine.startsWith("GET /?r=")) {
          handleColorRequest(currentLine);
        } else if (currentLine.startsWith("GET /fade?state=")) {
          handleFadeRequest(currentLine);
        } else if (currentLine.startsWith("GET /speed?value=")) {
          handleSpeedRequest(currentLine);
        } else if (currentLine.startsWith("GET /preset?index=")) {
          handlePresetRequest(currentLine);
        }
      }
    }
    
    client.stop();
    Serial.println("Client disconnected");
  }
}
 
void handleColorRequest(String request) {
  // 解析RGB值
  int redIndex = request.indexOf("r=");
  int greenIndex = request.indexOf("g=");
  int blueIndex = request.indexOf("b=");
  
  int redValue = request.substring(redIndex + 2, greenIndex - 1).toInt();
  int greenValue = request.substring(greenIndex + 2, blueIndex - 1).toInt();
  int blueValue = request.substring(blueIndex + 2).toInt();
  
  // 停止渐变效果
  fading = false;
  
  // 设置新颜色
  setColor(redValue, greenValue, blueValue);
  
  Serial.print("Set RGB to: ");
  Serial.print(redValue);
  Serial.print(", ");
  Serial.print(greenValue);
  Serial.print(", ");
  Serial.println(blueValue);
}
 
void handleFadeRequest(String request) {
  int stateIndex = request.indexOf("state=");
  String state = request.substring(stateIndex + 6);
  
  fading = (state == "on");
  
  Serial.print("Fade ");
  Serial.println(fading ? "enabled" : "disabled");
}
 
void handleSpeedRequest(String request) {
  int valueIndex = request.indexOf("value=");
  fadeSpeed = request.substring(valueIndex + 6).toInt();
  
  Serial.print("Fade speed set to: ");
  Serial.println(fadeSpeed);
}
 
void handlePresetRequest(String request) {
  int indexIndex = request.indexOf("index=");
  int index = request.substring(indexIndex + 6).toInt();
  
  if (index >= 0 && index < 6) {
    // 停止渐变效果
    fading = false;
    
    // 设置预设颜色
    setColor(presetColors[index][0], presetColors[index][1], presetColors[index][2]);
    
    Serial.print("Set preset color ");
    Serial.print(index);
    Serial.print(": ");
    Serial.print(presetColors[index][0]);
    Serial.print(", ");
    Serial.print(presetColors[index][1]);
    Serial.print(", ");
    Serial.println(presetColors[index][2]);
  }
}
 
void setColor(int r, int g, int b) {
  currentR = r;
  currentG = g;
  currentB = b;
  
  // 共阳极需要反向(如果是共阴极,去掉255-)
  analogWrite(redPin, 255 - r);
  analogWrite(greenPin, 255 - g);
  analogWrite(bluePin, 255 - b);
}
 
void fadeToRandomColor() {
  static int targetR = random(256);
  static int targetG = random(256);
  static int targetB = random(256);
  
  // 如果已经到达目标颜色,选择新的目标颜色
  if (currentR == targetR && currentG == targetG && currentB == targetB) {
    targetR = random(256);
    targetG = random(256);
    targetB = random(256);
  }
  
  // 逐步调整颜色
  if (currentR < targetR) currentR++;
  else if (currentR > targetR) currentR--;
  
  if (currentG < targetG) currentG++;
  else if (currentG > targetG) currentG--;
  
  if (currentB < targetB) currentB++;
  else if (currentB > targetB) currentB--;
  
  setColor(currentR, currentG, currentB);
}
 
void sendControlPage(WiFiClient &client) {
  client.println("<!DOCTYPE html>");
  client.println("<html>");
  client.println("<head>");
  client.println("<title>RGB LED Control</title>");
  client.println("<meta name='viewport' content='width=device-width, initial-scale=1'>");
  client.println("<style>");
  client.println("body { font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; }");
  client.println(".container { display: flex; flex-direction: column; gap: 20px; }");
  client.println(".control-group { display: flex; flex-direction: column; gap: 10px; padding: 15px; background: #f5f5f5; border-radius: 8px; }");
  client.println("input[type='color'] { width: 100%; height: 50px; cursor: pointer; }");
  client.println("input[type='range'] { width: 100%; cursor: pointer; }");
  client.println(".color-preview { width: 100%; height: 100px; border: 1px solid #ccc; border-radius: 8px; }");
  client.println("button { padding: 10px 15px; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }");
  client.println("button:hover { opacity: 0.8; }");
  client.println(".set-btn { background: #4CAF50; }");
  client.println(".set-btn:hover { background: #45a049; }");
  client.println(".fade-btn { background: ");
  client.println(fading ? "#f44336" : "#4CAF50");
  client.println("; }");
  client.println(".fade-btn:hover { background: ");
  client.println(fading ? "#d32f2f" : "#45a049");
  client.println("; }");
  client.println(".preset-btn { flex: 1; min-width: 60px; height: 40px; }");
  client.println(".preset-container { display: flex; gap: 10px; flex-wrap: wrap; }");
  client.println(".preset-red { background: #ff0000; }");
  client.println(".preset-green { background: #00ff00; }");
  client.println(".preset-blue { background: #0000ff; }");
  client.println(".preset-yellow { background: #ffff00; color: black; }");
  client.println(".preset-purple { background: #ff00ff; }");
  client.println(".preset-cyan { background: #00ffff; color: black; }");
  client.println("</style>");
  client.println("<script>");
  client.println("function updateFromColorPicker() {");
  client.println("  var color = document.getElementById('colorPicker').value;");
  client.println("  var r = parseInt(color.substr(1, 2), 16);");
  client.println("  var g = parseInt(color.substr(3, 2), 16);");
  client.println("  var b = parseInt(color.substr(5, 2), 16);");
  client.println("  document.getElementById('r').value = r;");
  client.println("  document.getElementById('g').value = g;");
  client.println("  document.getElementById('b').value = b;");
  client.println("  document.getElementById('rValue').textContent = r;");
  client.println("  document.getElementById('gValue').textContent = g;");
  client.println("  document.getElementById('bValue').textContent = b;");
  client.println("  updatePreview();");
  client.println("}");
  client.println("function updateFromSliders() {");
  client.println("  var r = document.getElementById('r').value;");
  client.println("  var g = document.getElementById('g').value;");
  client.println("  var b = document.getElementById('b').value;");
  client.println("  var hexColor = '#' + padZero(r.toString(16)) + padZero(g.toString(16)) + padZero(b.toString(16));");
  client.println("  document.getElementById('colorPicker').value = hexColor;");
  client.println("  document.getElementById('rValue').textContent = r;");
  client.println("  document.getElementById('gValue').textContent = g;");
  client.println("  document.getElementById('bValue').textContent = b;");
  client.println("  updatePreview();");
  client.println("}");
  client.println("function padZero(str) {");
  client.println("  return str.length == 1 ? '0' + str : str;");
  client.println("}");
  client.println("function updatePreview() {");
  client.println("  var r = document.getElementById('r').value;");
  client.println("  var g = document.getElementById('g').value;");
  client.println("  var b = document.getElementById('b').value;");
  client.println("  document.getElementById('colorPreview').style.backgroundColor = 'rgb(' + r + ',' + g + ',' + b + ')';");
  client.println("}");
  client.println("function sendColor() {");
  client.println("  var r = document.getElementById('r').value;");
  client.println("  var g = document.getElementById('g').value;");
  client.println("  var b = document.getElementById('b').value;");
  client.println("  window.location.href = '/?r=' + r + '&g=' + g + '&b=' + b;");
  client.println("}");
  client.println("function toggleFade() {");
  client.println("  var fadeState = document.getElementById('fadeToggle').textContent.includes('Start') ? 'on' : 'off';");
  client.println("  window.location.href = '/fade?state=' + fadeState;");
  client.println("}");
  client.println("function setSpeed() {");
  client.println("  var speed = document.getElementById('speed').value;");
  client.println("  window.location.href = '/speed?value=' + speed;");
  client.println("}");
  client.println("function setPreset(index) {");
  client.println("  window.location.href = '/preset?index=' + index;");
  client.println("}");
  client.println("</script>");
  client.println("</head>");
  client.println("<body>");
  client.println("<div class='container'>");
  client.println("<h1>RGB LED Control</h1>");
  
  // 颜色预览
  client.println("<div id='colorPreview' class='color-preview' style='background-color: rgb(");
  client.print(currentR);
  client.print(",");
  client.print(currentG);
  client.print(",");
  client.print(currentB);
  client.println(")'></div>");
  
  // 预设颜色按钮
  client.println("<div class='control-group'>");
  client.println("<h3>Preset Colors</h3>");
  client.println("<div class='preset-container'>");
  client.println("<button class='preset-btn preset-red' onclick='setPreset(0)'>Red</button>");
  client.println("<button class='preset-btn preset-green' onclick='setPreset(1)'>Green</button>");
  client.println("<button class='preset-btn preset-blue' onclick='setPreset(2)'>Blue</button>");
  client.println("<button class='preset-btn preset-yellow' onclick='setPreset(3)'>Yellow</button>");
  client.println("<button class='preset-btn preset-purple' onclick='setPreset(4)'>Purple</button>");
  client.println("<button class='preset-btn preset-cyan' onclick='setPreset(5)'>Cyan</button>");
  client.println("</div>");
  client.println("</div>");
  
  // 颜色选择器
  client.println("<div class='control-group'>");
  client.println("<label for='colorPicker'>Color Picker:</label>");
  client.print("<input type='color' id='colorPicker' value='#");
  client.print(padZero(String(currentR, HEX)));
  client.print(padZero(String(currentG, HEX)));
  client.print(padZero(String(currentB, HEX)));
  client.println("' onchange='updateFromColorPicker()'>");
  client.println("</div>");
  
  // 滑块控制
  client.println("<div class='control-group'>");
  client.println("<label for='r'>Red (0-255): <span id='rValue'>");
  client.print(currentR);
  client.println("</span></label>");
  client.print("<input type='range' id='r' name='r' min='0' max='255' value='");
  client.print(currentR);
  client.println("' oninput='updateFromSliders()'>");
  
  client.println("<label for='g'>Green (0-255): <span id='gValue'>");
  client.print(currentG);
  client.println("</span></label>");
  client.print("<input type='range' id='g' name='g' min='0' max='255' value='");
  client.print(currentG);
  client.println("' oninput='updateFromSliders()'>");
  
  client.println("<label for='b'>Blue (0-255): <span id='bValue'>");
  client.print(currentB);
  client.println("</span></label>");
  client.print("<input type='range' id='b' name='b' min='0' max='255' value='");
  client.print(currentB);
  client.println("' oninput='updateFromSliders()'>");
  client.println("</div>");
  
  // 设置按钮
  client.println("<button class='set-btn' onclick='sendColor()'>Set Color</button>");
  
  // 渐变控制
  client.println("<div class='control-group'>");
  client.println("<h3>Fade Effect</h3>");
  client.print("<button id='fadeToggle' class='fade-btn' onclick='toggleFade()'>");
  client.print(fading ? "Stop Fade Effect" : "Start Fade Effect");
  client.println("</button>");
  
  client.println("<label for='speed'>Fade Speed: <span id='speedValue'>");
  client.print(fadeSpeed);
  client.println("</span> ms</label>");
  client.print("<input type='range' id='speed' min='10' max='500' value='");
  client.print(fadeSpeed);
  client.println("' oninput='document.getElementById(\"speedValue\").textContent=this.value'>");
  client.println("<button class='set-btn' onclick='setSpeed()'>Set Speed</button>");
  client.println("</div>");
  
  client.println("</div>");
  client.println("</body>");
  client.println("</html>");
}
 
String padZero(String str) {
  return str.length() == 1 ? "0" + str : str;
}

What is your question?

Thank you for reply.But sorry there's no question just first time try to post on the forum。Good luck!

It would be interesting to compare an IoT based version of that.