#include "LEDs.h" #include #include #include #include #include #include void LEDs::setLightParam() { LightParam lp; /* * 关于分区方式请参考技术手册 */ /* * 对于只有一个分区的光源,以1Z4C为例,一个分区,四通道设置颜色 */ lp.zoneMode = 0; // 只有一个分区,分区方式设置为0即可 lp.currentZone = 1 ; // 只有一个分区,当前分区设置为1即可 lp.brightness = 100 ; // 当前分区的亮度,该光源只有一个分区,100即为光源整体的亮度 lp.colors = { 0,0,0,100 }; // 当前分区的颜色,该光源只有一个分区,{0,0,0,100}即为光源整体的颜色 /* * 对于存在多个分区的光源,以4Z4C为例,四个分区,四通道设置颜色 */ // 分区方式0,将光源视为一个整体。 // 设置以下参数,光源表现为类似单分区的光源,光源整体亮度为100,光源整体颜色为{100,0,0,0} lp.zoneMode = 0; lp.currentZone = 1; lp.brightness = 100; lp.colors = { 100,0,0,0 }; // 分区方式1,可独立控制各个分区 // 设置以下参数,将光源的分区1的亮度设置为100,颜色设置为{100,0,0,0} lp.zoneMode = 1; // 分区方式1,各分区可单独设置亮度、颜色 lp.currentZone = 1; // 当前分区序号1 lp.brightness = 100; // 分区序号1的分区的亮度 lp.colors = { 100,0,0,0 }; // 分区序号1的分区的颜色 // 分区方式2,可独立控制分区,但只能亮当前分区,其它分区则保持灭灯 // 设置以下参数,将光源的分区1的亮度设置为100,颜色设置为{100,0,0,0},其它分区保持灭灯 lp.zoneMode = 2; // 分区方式2 lp.currentZone = 1; // 当前分区序号1 lp.brightness = 100; // 分区序号1的分区的亮度 lp.colors = { 100,0,0,0 }; // 分区序号1的分区的颜色 } void LEDs::For1Z4C(const std::string& comName) { SW_SDK demo; std::vector devInfos; // 初始化 // 如果连接端口成功则尝试搜索所有连接的光源设备,并将设备信息保存在devInfos中。 auto res = demo.init(comName, devInfos); if (res) { std::cout << "connect to " << comName << " is success, get " << std::dec < dis(1, 4); auto x = dis(gen); if (x == 1) { std::cout << "Enter Pu-C work model\n"; demo.enterWorkModel(ModelType::PULSE_C, newAddr); } else if(x == 2) { std::cout << "Enter Pu-P work model\n"; demo.enterWorkModel(ModelType::PULSE_P, newAddr); } else if(x == 3) { std::cout << "Enter TTL_S work model\n"; demo.enterWorkModel(ModelType::TTL_S, newAddr); } else { std::cout << "Enter TTL_C work model\n"; demo.enterWorkModel(ModelType::TTL_C, newAddr); } #endif } void LEDs::For4Z4C(const std::string& comName) { SW_SDK demo; std::vector devInfos; // 初始化 // 如果连接端口成功则尝试搜索所有连接的光源设备,并将设备信息保存在devInfos中。 auto res = demo.init(comName, devInfos); if (res) { std::cout << "connect to " << comName << " is success, get " << std::dec << devInfos.size() << " devices\n"; helperDisplayDevice(devInfos); } else { std::cout << "connect to " << comName << " is failed, quit\n"; return; } if (devInfos.empty()) return; uint8_t newAddr = 12; // 修改光源设备的地址 res = demo.changeAddr(devInfos.front().UID, newAddr); if (res) { std::cout << "Change " << std::hex << helperUIDBytes2UIDDec(devInfos.front().UID) << " address is success\n"; helperChangeAddr(devInfos.front(), newAddr); } helperDisplayDevice(devInfos); // LightParam,用于设置分区、亮度、颜色 // 4Z4C光源有四个分区,分区方式为可选为0、1、2,四通道设置颜色 LightParam lp; #if 1 lp.zoneMode = 0; // 分区模式0,所有分区视为一个整体 lp.currentZone = 1 ; // 所有分区视为一个整体,当前分区置1即可 lp.brightness = 50; // 亮度 lp.colors = { 0,0,0,100 }; // 颜色 demo.setZoneAndColors(lp, newAddr); std::this_thread::sleep_for(std::chrono::seconds(1)); lp.zoneMode = 1; // 分区模式1,可单独控制各分区亮度、颜色 lp.brightness = 100; // 当前分区亮度 for (size_t i = 0; i < 4; ++i) { lp.currentZone = i % 4 + 1; // 当前分区 lp.colors = { 0,0,0,0 }; lp.colors.at(i % 4) = 100; // 当前分区颜色 demo.setZoneAndColors(lp, newAddr); std::this_thread::sleep_for(std::chrono::seconds(1)); } lp.zoneMode = 2; // 分区模式2,只能控制某一个分区的亮度、颜色 lp.currentZone = 1; // 当前分区 lp.brightness = 100; // 当前分区亮度 for (size_t i = 0; i < 4; ++i) { lp.currentZone = i % 4 + 1; // 当前分区 lp.colors = { 0,0,0,0 }; lp.colors.at((i + 1) % 4) = 100; lp.colors.at(i % 4) = 100; // 当前分区颜色 demo.setZoneAndColors(lp, newAddr); std::this_thread::sleep_for(std::chrono::seconds(1)); } // 将亮度设置为0,灭灯 lp.brightness = 0; demo.setZoneAndColors(lp, newAddr); std::this_thread::sleep_for(std::chrono::seconds(3)); #endif ModelType modelTypeSingle = ModelType::PULSE_P; // 工作模式Pu-P ModelType modelTypeMulti = ModelType::TTL_C; // 工作模式TTL_C TTL ttl = TTL::TTL_L; // 触发电平 uint8_t sceneSize = 4; // 场景总数 // 此处将四个场景保存为TTL_C工作模式 // 各场景亮灯持续时间为65535微秒,灭灯持续时间为65535微秒 lp.zoneMode = 0; lp.currentZone = 1 ; lp.brightness = 50; lp.colors = { 0,0,0,50 }; demo.setZoneAndColors(lp, newAddr); // 保存场景,场景序号1,分区方式为0,亮度50,颜色为{0,0,0,50} demo.saveScene(modelTypeMulti, ttl, newAddr, 1, sceneSize, 65535, 65535); lp.zoneMode = 1; lp.currentZone = 1; lp.brightness = 50; lp.colors = { 100,0,0,0 }; demo.setZoneAndColors(lp, newAddr); lp.currentZone = 2; lp.colors = { 0,100,0,0 }; demo.setZoneAndColors(lp, newAddr); lp.currentZone = 3; lp.colors = { 0,0,100,0 }; demo.setZoneAndColors(lp, newAddr); lp.currentZone = 4; lp.colors = { 0,0,0,100 }; demo.setZoneAndColors(lp, newAddr); // 保存场景,场景序号2,分区方式为1, // 分区1:亮度50,颜色为{100,0,0,0} // 分区2:亮度50,颜色为{0,100,0,0} // 分区3:亮度50,颜色为{0,0,100,0} // 分区4:亮度50,颜色为{0,0,0,100} demo.saveScene(modelTypeMulti, ttl, newAddr, 2, sceneSize, 65535, 65535); lp.zoneMode = 2; lp.currentZone = 2; lp.brightness = 100; lp.colors = { 100,100,0,0 }; demo.setZoneAndColors(lp, newAddr); // 保存场景,场景序号3,分区方式为2,分区2:亮度100,颜色为{100,100,0,0} demo.saveScene(modelTypeMulti, ttl, newAddr, 3, sceneSize, 65535, 65535); lp.zoneMode = 2; lp.currentZone = 4; lp.brightness = 100; lp.colors = { 0,0,100,100 }; demo.setZoneAndColors(lp, newAddr); // 保存场景,场景序号4,分区方式为2,分区4:亮度100,颜色为{0,0,100,100} demo.saveScene(modelTypeMulti, ttl, newAddr, 4, sceneSize, 65535, 65535); // 此处将单个场景保存为Pu-P工作模式 lp.zoneMode = 0; lp.currentZone = 1; lp.brightness = 200; lp.colors = { 50,50,50,50 }; demo.setZoneAndColors(lp, newAddr); // 保存场景,分区方式0,亮度200,颜色为{50,50,50,50} demo.saveScene(modelTypeSingle, ttl, newAddr, 1, 1, 65535, 0); // 进入某个工作模式 demo.enterWorkModel(modelTypeMulti, newAddr); //demo.enterWorkModel(modelTypeSingle, newAddr); #if 0 std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> dis(1, 4); //std::uniform_int_distribution<> dis(4, 4); auto x = dis(gen); if (x == 1) { std::cout << "Enter Pu-C work model\n"; demo.enterWorkModel(ModelType::PULSE_C, newAddr); } else if (x == 2) { std::cout << "Enter Pu-P work model\n"; demo.enterWorkModel(ModelType::PULSE_P, newAddr); } else if (x == 3) { std::cout << "Enter TTL_S work model\n"; demo.enterWorkModel(ModelType::TTL_S, newAddr); } else { std::cout << "Enter TTL_C work model\n"; demo.enterWorkModel(ModelType::TTL_C, newAddr); } #endif } void LEDs::For8Z8C(const std::string& comName) { SW_SDK demo; std::vector devInfos; // 初始化 // 如果连接端口成功则尝试搜索所有连接的光源设备,并将设备信息保存在devInfos中。 auto res = demo.init(comName, devInfos); if (res) { std::cout << "connect to " << comName << " is success, get " << std::dec << devInfos.size() << " devices\n"; helperDisplayDevice(devInfos); } else { std::cout << "connect to " << comName << " is failed, quit\n"; return; } if (devInfos.empty()) return; uint8_t newAddr = 12; // 修改光源设备的地址 res = demo.changeAddr(devInfos.front().UID, newAddr); if (res) { std::cout << "Change " << std::hex << helperUIDBytes2UIDDec(devInfos.front().UID) << " address is success\n"; helperChangeAddr(devInfos.front(), newAddr); } helperDisplayDevice(devInfos); // LightParam,用于设置分区、亮度、颜色 // 8Z8C光源有八个分区,分区方式为可选为0、1、2,四通道设置颜色 LightParam lp; #if 1 lp.zoneMode = 0; // 分区模式0,所有分区视为一个整体 lp.currentZone = 1; // 所有分区视为一个整体,当前分区置1即可 lp.brightness = 50; // 亮度 lp.colors = { 0,0,0,100,0,0,0,0 }; // 颜色 demo.setZoneAndColors(lp, newAddr); std::this_thread::sleep_for(std::chrono::seconds(1)); lp.zoneMode = 1; // 分区模式1,将每相邻的两个分区视为一个分区,只能控制某个分区亮度、颜色 lp.brightness = 100; // 当前分区亮度 for (size_t i = 0; i < 8; ++i) { lp.currentZone = i % 4 + 1; // 当前分区 lp.colors = { 0,0,0,0,0,0,0,0 }; lp.colors.at(i % 8) = 100; // 当前分区颜色 demo.setZoneAndColors(lp, newAddr); std::this_thread::sleep_for(std::chrono::seconds(1)); } lp.zoneMode = 2; // 分区模式2,只能控制某一个分区的亮度、颜色 lp.currentZone = 1; // 当前分区 lp.brightness = 100; // 当前分区亮度 for (size_t i = 0; i < 8; ++i) { lp.currentZone = i % 8 + 1; // 当前分区 lp.colors = { 0,0,0,0,0,0,0,0 }; lp.colors.at(i % 8) = 100; // 当前分区颜色 demo.setZoneAndColors(lp, newAddr); std::this_thread::sleep_for(std::chrono::seconds(1)); } // 将亮度设置为0,灭灯 lp.brightness = 0; demo.setZoneAndColors(lp, newAddr); std::this_thread::sleep_for(std::chrono::seconds(3)); #endif ModelType modelTypeSingle = ModelType::PULSE_P; // 工作模式Pu-P ModelType modelTypeMulti = ModelType::TTL_C; // 工作模式TTL_C TTL ttl = TTL::TTL_L; // 触发电平 uint8_t sceneSize = 4; // 场景总数 // 此处将四个场景保存为TTL_C工作模式 // 各场景亮灯持续时间为65535微秒,灭灯持续时间为65535微秒 lp.zoneMode = 0; lp.currentZone = 1; lp.brightness = 50; lp.colors = { 0,0,0,50,0,0,0,0 }; demo.setZoneAndColors(lp, newAddr); // 保存场景,场景序号1,分区方式为0,亮度50,颜色为{0,0,0,50,0,0,0,0} demo.saveScene(modelTypeMulti, ttl, newAddr, 1, sceneSize, 65535, 65535); lp.zoneMode = 1; lp.currentZone = 1; lp.brightness = 50; lp.colors = { 0,0,0,0,100,0,0,0 }; demo.setZoneAndColors(lp, newAddr); // 保存场景,场景序号2,分区方式为1, // 分区1:亮度50,颜色为{100,0,0,0,100,0,0,0} demo.saveScene(modelTypeMulti, ttl, newAddr, 2, sceneSize, 65535, 65535); lp.zoneMode = 2; lp.currentZone = 5; lp.brightness = 100; lp.colors = { 0,0,0,0,0,100,0,0 }; demo.setZoneAndColors(lp, newAddr); // 保存场景,场景序号3,分区方式为2,分区2:亮度100,颜色为{0,0,0,0,0,100,0,0} demo.saveScene(modelTypeMulti, ttl, newAddr, 3, sceneSize, 65535, 65535); lp.zoneMode = 2; lp.currentZone = 8; lp.brightness = 100; lp.colors = { 0,0,0,0,0,0,100,0 }; demo.setZoneAndColors(lp, newAddr); // 保存场景,场景序号4,分区方式为2,分区4:亮度100,颜色为{0,0,0,0,0,0,100,0} demo.saveScene(modelTypeMulti, ttl, newAddr, 4, sceneSize, 65535, 65535); // 此处将单个场景保存为Pu-P工作模式 lp.zoneMode = 0; lp.currentZone = 1; lp.brightness = 200; lp.colors = { 50,50,50,50,0,0,0,0 }; demo.setZoneAndColors(lp, newAddr); // 保存场景,分区方式0,亮度200,颜色为{50,50,50,50,0,0,0,0} demo.saveScene(modelTypeSingle, ttl, newAddr, 1, 1, 65535, 0); // 进入某个工作模式 demo.enterWorkModel(modelTypeMulti, newAddr); //demo.enterWorkModel(modelTypeSingle, newAddr); #if 0 std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> dis(1, 4); //std::uniform_int_distribution<> dis(4, 4); auto x = dis(gen); if (x == 1) { std::cout << "Enter Pu-C work model\n"; demo.enterWorkModel(ModelType::PULSE_C, newAddr); } else if (x == 2) { std::cout << "Enter Pu-P work model\n"; demo.enterWorkModel(ModelType::PULSE_P, newAddr); } else if (x == 3) { std::cout << "Enter TTL_S work model\n"; demo.enterWorkModel(ModelType::TTL_S, newAddr); } else { std::cout << "Enter TTL_C work model\n"; demo.enterWorkModel(ModelType::TTL_C, newAddr); } #endif } uint64_t LEDs::helperUIDBytes2UIDDec(const std::vector& UID) { assert(UID.size() == 6); uint64_t res = 0; for (size_t i = 0; i < UID.size(); ++i) { uint64_t x = static_cast(UID[i]); x <<= (8 * (UID.size() - i - 1)); res += x; } return res; } void LEDs::helperDisplayDevice(const std::vector& devInfos) { std::cout << "\n----Display All Devices(" << devInfos.size() << "):----\n"; for (const auto& dev : devInfos) { std::cout << "UID: 0x" << std::hex << std::setw(12) << std::setfill('0') << helperUIDBytes2UIDDec(dev.UID) << " | " << std::setfill(' ') << "ADDR: " << std::setw(4) << std::left << std::dec << static_cast(dev.address) << " | " << "SN: " << std::setw(40) << std::left << dev.productModel << " | " << "ZONE_SIZE: " << std::setw(4) << std::left << std::dec << dev.zoneSize << " | " << "COLOR_SIZE: " << std::setw(4) << std::left << std::dec << dev.colorSize << std::endl; } std::cout << std::endl; } void LEDs::helperChangeAddr(DevInfo& devInfo, uint8_t addr) { devInfo.address = addr; } void LEDs::testInitLoop(const std::string& comName, size_t loopCnt, size_t expectedNum) { size_t errorTimes = 0; size_t sleepSeconds = 1; for (size_t i = 0; i < loopCnt; ++i) { { std::cout << "Loop init() times: " << std::dec << i + 1 << std::endl; SW_SDK demo; std::vector devInfos; auto begin = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); std::cout << std::boolalpha << demo.init(comName, devInfos) << std::endl; auto end = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); std::cout << "init() elapsed: " << std::dec << end.count() - begin.count() << "ms, get dev num: " << devInfos.size() << std::endl; helperDisplayDevice(devInfos); if (devInfos.empty()) continue; #if 1 std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> dis(1, devInfos.size()); for (auto& dev : devInfos) { uint8_t addr = static_cast(dis(gen)); std::cout << std::hex << helperUIDBytes2UIDDec(dev.UID) << " will change addr to " << std::dec << static_cast(addr) << std::endl; auto res = demo.changeAddr(dev.UID, addr); if (res) helperChangeAddr(dev, addr); } helperDisplayDevice(devInfos); if (devInfos.size() != expectedNum) { ++errorTimes; sleepSeconds = 10; } else { sleepSeconds = 1; } std::cout << "Error times: " << std::dec << errorTimes << " in looping(" << std::dec << i + 1 << ")\n"; #endif } std::this_thread::sleep_for(std::chrono::seconds(sleepSeconds)); } std::cout << "Finished, error times: " << std::dec << errorTimes << std::endl; }