fonchain-container/mcuClients/clientFor5050RGB/clientFor5050RGB.ino

279 lines
8.8 KiB
Arduino
Raw Normal View History

2024-05-27 10:18:17 +00:00
#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);
}