#include #include #include #include #include //-------------设备配置 const char mchId[6] = "06000"; //货柜编号 bool setupFlag = false; //初始化标志 unsigned long currentTime = 0; //当前时间 //-------------LED指示灯配置 struct LEDInfo { int ledNumber; // LED的数字编号 uint32_t color; // RGB颜色,使用NeoPixel库中的类型 int status; //状态 1=常亮 2=闪烁 int flashFlag; //闪烁状态的亮灭标识 unsigned long lastFlashTime; }; #define NUM_LEDS 60 //LED指示灯数量 #define PIN_DIO 2 //LED控制引脚位 Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN_DIO, NEO_GRB + NEO_KHZ800); LEDInfo leds[NUM_LEDS]; // 创建一个LED信息数组 unsigned long showCheckSpace = 500; //led亮灯检测间隔,ms unsigned long lastShowTime = 0; //上一次亮灯检测时间 //---------------wifi配置 const char* ssid = "chenyao_5G"; const char* password = "fontree008"; WiFiClient client; //---------------服务端配置 const char* serverIP = "192.168.1.77"; const int serverPort = 8888; const char cmd_reg[4] = "001"; //注册指令 const char cmd_ping[4] = "002"; //ping指令 char buff[512]; //tcp读取缓冲区 int rnum = 0; //tcp读取索引 bool readed = false; void setup() { Serial.begin(115200); initLED(); connectWifi(); connectTcpServer(); setupFlag = true; } void loop() { check(); if (setupFlag) { bindAndHandleMessage(); ledShow(); } // effect_colorLoop(1); // allPixelsOn(strip.Color(255, 255, 255)); // 点亮所有LED,颜色为白色 // delay(1000); } //==============================================网络========================================================== // wifi 连接 void connectWifi() { WiFi.begin(ssid, password); Serial.print("WIFI Connecting"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); Serial.print("WIFI Connected, IP address: "); Serial.println(WiFi.localIP()); } // 连接tcp服务端 void connectTcpServer() { Serial.print("TCP Server Connecting"); while (!client.connected()) { if (client.connect(serverIP, serverPort)) { delay(500); tcpSend_register(); Serial.println(); Serial.println("TCP Server Connected"); } else { delay(500); Serial.print("."); } } } void check() { if (WiFi.status() != WL_CONNECTED) { connectWifi(); } if (!client.connected()) { connectTcpServer(); } } //==============================================LED灯效果========================================================== // 初始化LED,使之都处于关闭状态 void initLED() { strip.begin(); strip.show(); } // 所有灯亮指定颜色 void allPixelsOn(uint32_t color) { for (int i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, color); } strip.show(); } // 红绿蓝三色循环 void effect_colorLoop(int times) { for (int i = 0; i < times; i++) { allPixelsOn(strip.Color(255, 0, 0)); delay(1000); allPixelsOn(strip.Color(0, 255, 0)); delay(1000); allPixelsOn(strip.Color(0, 0, 255)); delay(1000); } } // 流水灯效果 void effect_runningWater(int times) { for (int i = 0; i < times; i++) { colorWipe(strip.Color(255, 0, 0), 50); // 红色流水灯 colorWipe(strip.Color(0, 255, 0), 50); // 绿色流水灯 colorWipe(strip.Color(0, 0, 255), 50); // 蓝色流水灯 } } // 指定一种颜色实现流水灯效果 void colorWipe(uint32_t color, int wait) { for (int i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, color); strip.show(); delay(wait); } } //存储led状态 void ledSave(int ledNum, uint8_t r, uint8_t g, uint8_t b, uint8_t lig, int status) { leds[ledNum - 1].ledNumber = ledNum; leds[ledNum - 1].status = status; if (lig == 0) { leds[ledNum - 1].color = strip.Color(r, g, b); } else { // 使用亮度换算rgb颜色 leds[ledNum - 1].color = strip.Color((r * lig) / 255, (g * lig) / 255, (b * lig)); } } //轮播led灯 void ledShow() { currentTime = millis(); if (currentTime - lastShowTime >= showCheckSpace) { lastShowTime = currentTime; for (int i = 0; i < NUM_LEDS; ++i) { if (leds[i].status == 1) { strip.setPixelColor(i, leds[i].color); } else if (leds[i].status == 2) { if (currentTime - leds[i].lastFlashTime >= 1000) { // 每500毫秒切换一次状态 if (leds[i].flashFlag == 0) { strip.setPixelColor(i, leds[i].color); } else { strip.setPixelColor(i, strip.Color(0, 0, 0)); } leds[i].flashFlag = !leds[i].flashFlag; // 切换flash状态 leds[i].lastFlashTime = currentTime; // 更新上次闪烁时间 } } } strip.show(); } } //保存led状态并展示 void ledSaveAndShow(int ledNum, uint8_t r, uint8_t g, uint8_t b, uint8_t lig, int status) { if (status == 1) { if (lig == 0) { leds[ledNum - 1].color = strip.Color(r, g, b); } else { // 计算实际的颜色值,考虑到整体亮度 leds[ledNum - 1].color = strip.Color((r * lig) / 255, (g * lig) / 255, (b * lig)); } for (int i = 0; i < NUM_LEDS; ++i) { strip.setPixelColor(i, leds[i].color); } strip.show(); } } //调节颜色和亮度 void setSinglePixelBrightness(int ledIndex, uint8_t r, uint8_t g, uint8_t b, uint8_t brightness) { // 计算实际的颜色值,考虑到整体亮度 uint8_t actualRed = (r * brightness) / 255; uint8_t actualGreen = (g * brightness) / 255; uint8_t actualBlue = (b * brightness) / 255; // 设置NeoPixel的颜色 strip.setPixelColor(ledIndex, strip.Color(actualRed, actualGreen, actualBlue)); } //------------------------------------------------消息接收/发送------------------------------------------------ void bindAndHandleMessage() { while (client.available()) { client.readBytes(buff, sizeof(buff)); String data = String(buff); Serial.println("acc:" + data); readed = true; break; } if (readed) { String cmd = String(buff[0]) + String(buff[1]) + String(buff[2]); Serial.println("Received cmd:" + cmd); if (cmd == "002") { //ping pong tcpSend_pong(); } else if (cmd == "003") { //led set // int ledNum= atoi(String(buff[9]).c_str())*100+atoi(String(buff[10]).c_str())*10+atoi(String(buff[11]).c_str()); // String strLedNum=to_string(ledNum); int ledNum = buff_int(8, 10); int status = buff_int(11, 11); int r = buff_int(12, 14); int g = buff_int(15, 17); int b = buff_int(18, 20); int lig = buff_int(21, 23); String strLedNum = to_string(ledNum); String strStatus = to_string(status); String strR = to_string(r); String strG = to_string(g); String strB = to_string(b); String strLig = to_string(lig); Serial.println("Received cmd:" + cmd + " LedNum:" + strLedNum + " status:" + strStatus + " r:" + strR + " g:" + strG + " b:" + strB + " lig:" + strLig); ledSave(ledNum, r, g, b, lig, status); } else { Serial.println("Unknow cmd"); } rnum = 0; readed = false; memset(buff, 0, 512); } } void tcpSend_register() { String msg = String(cmd_reg) + String(mchId); client.println(msg); } void tcpSend_pong() { String msg = String(cmd_ping) + String(mchId) + "pong"; Serial.println("send pong" + msg); client.println(msg); } // void readMsg(from,to)String{ // } // //------------------------------------------------消息接收/发送------------------------------------------------ String to_string(int num) { // 指定返回类型为 String String result; // 创建一个 String 对象,注意这里使用不同的变量名以避免与参数名或函数名冲突 result += num; // 将整数转换为 String 并添加到 result return result; // 返回 String 对象 } String buff_string(int start, int end) { if (start < 0 || end >= sizeof(buff) || start > end) { return ""; // 如果不在范围内,返回空字符串 } String result; for (int i = start; i <= end; ++i) { result += buff[i]; // 将 buff 中的字符添加到 result 字符串中 } return result; // 返回构建的字符串 } int buff_int(int start, int end) { // 检查 start 和 end 是否在 buff 的有效范围内 if (start < 0 || end >= sizeof(buff) || start > end) { // 如果索引不合理,返回 0 或者其他错误代码 return 0; } // 计算子字符串的长度 int length = end - start + 1; // 从 buff 中提取子字符串 char substr[length + 1]; // +1 为了存储字符串结束符 '\0' strncpy(substr, &buff[start], length); substr[length] = '\0'; // 确保字符串以 '\0' 结尾 // 将子字符串转换为整数 return atoi(substr); }