本帖最后由 tanxw 于 2020-1-15 20:17 编辑
准备工作 1. ESP8266 (客户端) 2. WS2812 (穿越机上的彩灯也可以) 3. 安装GoLang (服务端需要编译) 4. 在PC端添加环境变量变量名:GOPROXY变量值:https://goproxy.io 5. ArduinoIDE or Visual Code + PIO 6.为ArduinoIDE orVisual Code PIO 的库管理中添加ArduinoJson Adafruit_NeoPixel 8. 保存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);
- }
复制代码
|