tanxw 发表于 2020-1-15 10:58:47

RGB氛围灯

本帖最后由 tanxw 于 2020-1-15 20:17 编辑

准备工作1. ESP8266 (客户端)2. WS2812 (穿越机上的彩灯也可以)3. 安装GoLang (服务端需要编译)4. 在PC端添加环境变量变量名:GOPROXY变量值:https://goproxy.io5. ArduinoIDE or Visual Code + PIO6.为ArduinoIDE orVisual Code PIO 的库管理中添加ArduinoJson Adafruit_NeoPixel8. 保存GoLang代码为app.go 用CMD进入所在目录执行       go build app.go 得到执行文件,双击运行
注意事项:
GoLang安装后手动拉取依赖包:
go get "github.com/cenkalti/dominantcolor"
go get "github.com/kbinani/screenshot"


ESP8266
通过库管理器安装:ArduinoJson, Adafruit_NeoPixel
原理:GoLang应用程序作为TCP服务端运行在PC端,Esp8266 作为客户端连接。
服务端监听到连接,开启一个协程。并循环获截取屏幕,获取屏幕主色调。通过TCP发送给Esp8266,Esp8266在收到数据的时候。解析出RGB并通过ws2812进行显示。
建议放在屏幕后面,效果美滋滋。 理论上,可以支持多个ESP8266客户端连接。多的话足以点亮整房子与你的电脑当前画面主色调同步。RGB!大家有条件可以试试 加油 奥力给!
对了,如果真有条件的话。可以把为getScreenshotColor方法加同步锁,或者把RGB值放到全局

为何在这里发帖,各位老哥看到的话能否把diy r9m接收机的原理图发份给我。tanxwai@gmail.com 在下金币实在不够。
GoLang端代码


package main

import (
       "encoding/json"
       "image/color"
       "log"
       "net"
       "os"
       "time"

       "github.com/cenkalti/dominantcolor"
       "github.com/kbinani/screenshot"
)

func main() {
       listener,err := net.Listen("tcp", "192.168.31.48:8099") // 这里可以改为本机ip
       if err != nil {
            log.Fatal(err)
       }
       defer listener.Close()
       for{
            conn, err := listener.Accept()
            iferr != nil {
                     log.Fatal(err)
            }
            log.Println("onConnect:",conn.RemoteAddr().String())
            go handleConnect(conn)
       }
}

// handleConnect 客户端连接处理器
func handleConnect(conn net.Conn) {
       defer conn.Close()
       for {
            data,_ := json.Marshal(getScreenshotColor())
            log.Println("sendData:", string(data)+"\n")
            _,err := conn.Write([]byte(string(data) + "\n"))
            iferr != nil {
                     log.Println("wan:",err.Error())
                     return
            }
            time.Sleep(time.Millisecond* 200)
       }
}

// getScreenshotColor 获取屏幕颜色
func getScreenshotColor() color.RGBA {
       bounds := screenshot.GetDisplayBounds(0)
       img, err:= screenshot.CaptureRect(bounds)
       checkError(err)
       return dominantcolor.Find(img)
}

func checkError(err error) {
       if err != nil {
            log.Fatalln(err)
            os.Exit(1)
       }
}






ESP8266端代码

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <Adafruit_NeoPixel.h>

const char *ssid = "wifi"; // 你家的WiFi名
const char *password = "xiaog123"; // 你家的WiFi密码
WiFiClient client;

const uint16_t PixelCount = 12; // thisexample assumes 4 pixels, making it smaller will cause a failure
const uint8_t PixelPin = D4;    // make sure to set this to the correctpin, ignored for Esp8266

StaticJsonDocument<200> doc;

Adafruit_NeoPixel pixels =Adafruit_NeoPixel(PixelCount, PixelPin, NEO_GRB + NEO_KHZ800);

void tryConnect()
{
while (!client.connect("192.168.31.48", 8099)) // 这里改为电脑的IP地址,
{
   Serial.println("connection failed");
   delay(500);
}
}

void setup()
{

pixels.begin();
Serial.begin(115200);
delay(10);
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
   delay(500);
   Serial.print(".");
}
Serial.println("");
Serial.print("Connected, IP address: ");
Serial.println(WiFi.localIP());
}

void loop()
{
if(!client.connected())
{
   tryConnect();
   Serial.println("connect !");
}

if(client.available())
{
   String line = client.readStringUntil('\n');
   Serial.printf("onMessage:{%s}\n", line.c_str());
   deserializeJson(doc, line);
   auto r = doc["R"].as<int>();
   auto g = doc["G"].as<int>();
   auto b = doc["B"].as<int>();
   Serial.printf("R:{%d}, B:{%d}, G:{%d}\n", r, b, g);
   doc.clear();
   for (size_t i = 0; i < PixelCount; i++)
    {
   pixels.setPixelColor(i, pixels.Color(r, g, b));
    }
   pixels.show();
}
delay(200);
}

寂静天空house 发表于 2020-4-1 16:04:48

水贴赚积分,感谢楼主

寂静天空house 发表于 2020-4-1 16:05:17

同求原理图,谢谢

xiancai 发表于 2020-4-12 15:01:53

水贴赚积分,感谢楼主

jamiy 发表于 2020-4-12 20:52:46


水贴赚积分,感谢楼主
页: [1]
查看完整版本: RGB氛围灯