fonchain-container/mcuClients/clientFor5050RGB/clientFor5050RGB.ino
2024-05-27 18:18:17 +08:00

279 lines
8.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <Adafruit_NeoPixel.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <string.h>
#include <cstdlib>
//-------------设备配置
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);
}