瀚文(HelloWord)智能键盘项目深度剖析:从0到1的全流程解读
瀚文(HelloWord)智能键盘项目深度剖析:从0到1的全流程解读
一、项目整体概述
瀚文(HelloWord)智能键盘是一款多功能、模块化的智能机械键盘,由三大部分组成:键盘输入模块、可替换的多功能交互模块(Dynamic组件)以及扩展坞底座。项目完全开源,涵盖了硬件设计、固件开发、3D模型设计等全方位内容。
该键盘的特点包括:
- 左侧可更换的多功能交互组件(默认为带电子墨水屏和FOC力反馈旋钮的Dynamic组件)
- 基于ARM Cortex-M的定制固件系统
- 基于移位寄存器的高效按键扫描电路
- 模块化设计,可独立使用或组合使用
二、项目文件夹结构及功能解析
2.1 .idea
文件夹
这是JetBrains IDE(如CLion)的配置文件夹,包含项目设置信息。对于初学者来说,可以暂时忽略。
2.2 1.Hardware
文件夹
此文件夹包含键盘硬件设计文件,主要是各模块的电路原理图:
1.Hardware/
├── 工程链接.txt # 立创EDA项目链接
├── SCH_HelloWord-Keyboard_2022-07-31.pdf # 主键盘电路图
├── SCH_HelloWord-Ctrl_2022-07-31.pdf # 左侧Dynamic组件电路图
├── SCH_HelloWord-TypeC_2022-07-31.pdf # TypeC接口电路图
└── [其他PCB模块电路图] # 各功能模块电路图
核心技术分析:
键盘硬件采用了高度模块化设计,共有10块PCB组成不同功能模块:
// 键盘PCB模块组成及功能
PCB_Modules = {"HelloWord-Keyboard": "主键盘PCB,STM32F103控制器,按键输入+RGB灯","HelloWord-Ctrl": "Dynamic组件PCB,STM32F405控制器,带FOC力反馈旋钮和墨水屏","HelloWord-Connector": "主键盘连接底座的触点PCB","HelloWord-TypeC": "底座TypeC接口PCB,带电源管理和USB-Hub","HelloWord-Hub1": "底座USB-A接口转接PCB","HelloWord-Hub2": "底座USB-A母座PCB","HelloWord-OLED": "OLED屏幕驱动电路","HelloWord-TouchBar": "电容触摸条模块PCB","HelloWord-Encoder": "磁编码器PCB","[其他模块]": "..."
}
这种模块化设计使各功能块可以独立工作,也能通过底座联动,大大提高了灵活性。
2.3 2.Firmware
文件夹
包含键盘和Dynamic组件的固件源码及预编译固件:
2.Firmware/
├── HelloWord-Keyboard-fw/ # 主键盘固件
├── HelloWord-Dynamic-fw/ # Dynamic组件固件
└── _Release/ # 预编译的bin固件文件
2.3.1 按键映射实现
// 键盘固件中的按键映射方式(hw_keyboard.h)
const uint8_t keyMap[KEYMAP_NUM][IO_NUMBER] = {// 层0:硬件按键编号 -> 标准布局位置映射{9, 8, 7, 6, 5, 4, 3, 2, 1, 0, // 0-9号按键的映射19, 18, 17, 16, 15, 14, 13, 12, 11, 10, // 10-19号按键的映射// ... 更多按键映射},// 层1:标准布局(正常使用时的键值){ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, // 基本按键// ... 标准键盘布局},// 层2、3等:自定义功能层// ...
};
代码解析:
keyMap
是一个二维数组,第一维表示映射层数,第二维表示按键序号- 第0层负责将PCB上物理按键位置映射到标准键盘布局位置
- 第1层是标准键盘键值映射
- 第2层及以上是自定义功能层,可以将任意按键映射为任意功能
通过软件映射,PCB上的按键可以任意放置,不需要遵循传统键盘的布局限制,这极大提高了设计灵活性。
2.3.2 按键滤波算法
// 对称延迟独立滤波(简化版)
void HWKeyboard::ScanKeys()
{// 第一次扫描uint8_t buffer1[IO_NUMBER/8] = {0};ScanIO(buffer1);// 延迟一段时间(微秒级)DelayUs(DEBOUNCE_TIME);// 第二次扫描uint8_t buffer2[IO_NUMBER/8] = {0};ScanIO(buffer2);// 比较两次结果,确保按键状态稳定for(uint8_t i = 0; i < IO_NUMBER/8; i++){if((buffer1[i] ^ lastBuffer[i]) & (buffer1[i] ^ buffer2[i]) == 0){// 状态稳定,更新按键状态keysState[i] = buffer2[i];}lastBuffer[i] = buffer2[i];}
}
代码解析:
- 这段代码实现了"对称延迟独立滤波",对每个按键单独进行抖动过滤
- 两次扫描之间间隔微秒级延时,只有两次状态一致才认为按键状态有效
- 这种方式比传统全局滤波更高效,可以保证每个按键独立处理,提高响应速度
2.3.3 RGB灯效控制
// RGB控制示例代码
void HWKeyboard::SyncLights()
{// 将RGB数据转换为WS2812B时序数据for(uint8_t i = 0; i < LED_NUMBER; i++){// R、G、B依次转换为24位时序数据ConvertToSPIBits(rgbBuffer[i].g); // WS2812B需要GRB顺序ConvertToSPIBits(rgbBuffer[i].r);ConvertToSPIBits(rgbBuffer[i].b);}// 通过SPI+DMA方式高速发送数据HAL_SPI_Transmit_DMA(&hspi1, spiBuffer, SPI_BUFFER_SIZE);
}// 灯效示例
void RainbowEffect()
{static uint8_t hue = 0;hue++;for(uint8_t i = 0; i < LED_NUMBER; i++){// 计算每个LED的色相偏移uint8_t pixelHue = hue + (i * 255 / LED_NUMBER);// 将HSV转换为RGBColor_t color = HSV2RGB(pixelHue, 255, 128);// 设置RGB缓冲区keyboard.SetRgbBuffer(i, color);}// 同步发送到LEDkeyboard.SyncLights();
}
代码解析:
- 通过SPI+DMA模拟WS2812B时序,相比传统位带操作大幅提高效率
- RGB灯效可以轻松通过修改
rgbBuffer
来实现各种动态效果 - 支持单独控制每个按键的RGB颜色,实现丰富的灯光效果
2.4 3.Software
文件夹
包含键盘的PC端配套软件:
3.Software/
├── 说明.md # 软件使用说明
├── 修改墨水屏图片.zip # 墨水屏图片修改工具
└── HelloWord_plugin.js # 键盘插件脚本
功能分析:
- 墨水屏图片修改工具:允许用户自定义墨水屏显示内容
- JavaScript插件:用于扩展键盘功能,可能用于自定义快捷键或动作
2.5 4.Tools
文件夹
提供开发和使用必要的工具软件:
4.Tools/
├── 安装USB驱动/ # USB驱动程序
├── HID Descriptor Tool/ # USB HID描述符工具
└── STM32 ST-LINK Utility v4.5.0.exe # STM32烧录工具
工具用途:
- ST-LINK Utility:用于将编译好的固件烧录到STM32芯片
- USB驱动:确保Windows系统正确识别键盘设备
- HID工具:帮助开发者编写和测试USB HID描述符
2.6 5.3D Model
文件夹
提供键盘外壳和机构的3D模型文件:
5.3D Model/
├── 瀚文扩展版/ # 扩展版3D模型文件
├── 瀚文基础版/ # 基础版3D模型文件
└── 瀚文全套模型STEP.stp # 完整的STEP格式3D模型
结构特点:
- 模块化结构设计,包括底座、主键盘和左侧可更换模块
- 提供STEP格式文件,兼容大多数3D建模软件
- 支持3D打印制作,方便DIY爱好者复刻
2.7 5.Docs
文件夹
包含项目相关的参考资料和文档:
5.Docs/
├── 1.Datasheet/ # 项目中使用的芯片数据手册
├── 2.Images/ # 项目图片资源
└── HID用途表1.12.pdf # USB HID协议参考文档
文档内容:
- 芯片数据手册:提供项目使用的电子元器件详细规格
- 项目图片:用于README和文档展示
- HID协议文档:USB HID通信协议参考
三、技术亮点分析
3.1 移位寄存器按键扫描技术
传统键盘通常采用行列式扫描,而瀚文键盘使用移位寄存器(74HC165)实现:
// 传统行列式扫描
void ScanMatrix(uint8_t* keyStates)
{// 逐行扫描for(uint8_t row = 0; row < ROWS; row++){// 设置当前行为低电平SetRowLow(row);// 读取所有列状态for(uint8_t col = 0; col < COLS; col++){keyStates[row * COLS + col] = ReadColPin(col);}// 恢复当前行为高电平SetRowHigh(row);}
}// 瀚文的移位寄存器扫描(简化版)
void ScanShiftRegister(uint8_t* keyStates)
{// 加载按键状态到移位寄存器HAL_GPIO_WritePin(LOAD_GPIO_Port, LOAD_Pin, GPIO_PIN_RESET);HAL_GPIO_WritePin(LOAD_GPIO_Port, LOAD_Pin, GPIO_PIN_SET);// 通过SPI读取所有按键状态(一次性读取多个按键)HAL_SPI_Receive(&hspi2, keyStates, IO_NUMBER/8, HAL_MAX_DELAY);
}
优势对比:
- 速度更快:SPI接口可达数MHz,一次读取多个按键
- 完全无冲突(NKRO):每个按键都是独立的,无鬼键问题
- 布局灵活:PCB布局与扫描顺序解耦,任意布局都可以通过软件重映射
3.2 FOC力反馈旋钮实现
Dynamic模块中实现了基于FOC(Field Oriented Control)的力反馈旋钮:
// FOC控制核心代码(简化版)
void FOC_Controller::update()
{// 1. 读取编码器位置float shaftAngle = encoder->getAngle();// 2. 计算电角度float electricalAngle = shaftAngle * pole_pairs;// 3. 计算所需的电机扭矩float torque = calculateTorque();// 4. FOC电流控制float Uq = PID(targetCurrent, measuredCurrent);// 5. 计算三相电压float Ua, Ub, Uc;SinCos3Phase(electricalAngle, torque, Uq, &Ua, &Ub, &Uc);// 6. 输出PWMsetPWM(Ua, Ub, Uc);
}// 不同触感效果实现
void DynamicEffect::detentEffect()
{// 实现齿轮槽卡顿感float angle = encoder->getAngle();float detent = sin(angle * detentsPerRevolution) * detentStrength;motor->setTorque(detent);
}
技术解析:
- 使用AS5047P精密磁编码器检测旋钮位置
- 基于FOC算法控制无刷电机,提供精确的力反馈
- 通过软件定义不同的力触感模型,可以模拟机械齿轮、阻尼、弹簧等多种感觉
3.3 模块化通信架构
键盘底座、主键盘和左侧模块之间建立了复杂的通信机制:
// 模块间通信协议(简化版)
typedef struct {uint8_t header[2]; // 0xAA, 0x55 固定头uint8_t type; // 消息类型uint8_t length; // 数据长度uint8_t data[32]; // 数据负载uint8_t checksum; // 校验和
} ModuleMessage_t;// 发送消息到其他模块
void sendToModule(uint8_t moduleID, uint8_t msgType, uint8_t* data, uint8_t len)
{ModuleMessage_t msg;// 填充消息头msg.header[0] = 0xAA;msg.header[1] = 0x55;msg.type = msgType;msg.length = len;// 复制数据memcpy(msg.data, data, len);// 计算校验和msg.checksum = calculateChecksum(&msg);// 根据模块ID选择发送接口switch(moduleID) {case MODULE_KEYBOARD:UART_SendData(UART_KEYBOARD, (uint8_t*)&msg, len+5);break;case MODULE_DYNAMIC:UART_SendData(UART_DYNAMIC, (uint8_t*)&msg, len+5);break;// 其他模块...}
}
架构优势:
- 基于串口通信的轻量级协议,延迟低,实现简单
- 模块可独立工作,也可协同工作,增强系统弹性
- 标准化消息格式,便于扩展新模块和功能
四、从0到1的开发指南
4.1 准备开发环境
# 1. 安装必要软件
- STM32CubeIDE 或 CLion+OpenOCD (编译环境)
- STM32 ST-LINK Utility (烧录工具)
- 立创EDA专业版 (查看或修改硬件)# 2. 克隆代码仓库
git clone https://github.com/peng-zhihui/HelloWord-Keyboard.git# 3. 打开项目
# 对于STM32CubeIDE:
- 打开STM32CubeIDE
- File -> Import -> Existing Projects into Workspace
- 选择HelloWord-Keyboard-fw或HelloWord-Dynamic-fw文件夹# 对于CLion:
- 打开CLion
- File -> Open
- 选择对应固件文件夹
- 配置CMake和OpenOCD(参考README中提到的教程)
4.2 硬件制作流程
# 1. PCB制作
- 下载PCB源文件(立创EDA格式)
- 通过立创EDA打开项目,查看或修改设计
- 生成Gerber文件,发送给PCB制造商
- 根据BOM表采购电子元器件
- 焊接组装PCB# 2. 结构件制作
- 下载3D模型文件
- 使用3D打印机打印结构件或
- 将STEP文件发送给CNC加工厂商制作铝材外壳
4.3 自定义按键映射
要修改键盘的按键映射,需要编辑hw_keyboard.h
文件中的映射数组:
// 步骤1:了解物理按键与编号的对应关系
// 按键编号是按照74HC165芯片的连接顺序确定的// 步骤2:修改第0层映射(硬件映射到标准位置)
const uint8_t keyMap[KEYMAP_NUM][IO_NUMBER] = {{// 这里填入物理按键编号,映射到标准键盘位置9, 8, 7, 6, 5, /* ... 更多按键 */},// 步骤3:修改第1层及更高层(功能映射){ESC, F1, F2, F3, F4, /* ... 更多按键 */},// 自定义功能层(如宏、媒体键等){/* ... 自定义功能键映射 ... */}
};// 步骤4:编译并烧录固件
实用技巧:
- 可以先通过调试模式打印出所有按键的物理编号,然后逐一确认
- 建议使用枚举常量定义按键功能,增强代码可读性
- 不同层可以通过组合键(如Fn+其他键)切换
4.4 添加自定义RGB灯效
// 步骤1:在hw_keyboard.h中添加新的灯效函数
void MyCustomEffect()
{static uint32_t lastTime = 0;static uint8_t position = 0;// 控制更新速率uint32_t currentTime = HAL_GetTick();if (currentTime - lastTime < 50) return;lastTime = currentTime;// 清空所有LEDfor (uint8_t i = 0; i < LED_NUMBER; i++) {keyboard.SetRgbBuffer(i, {0, 0, 0});}// 设置流动的LEDfor (uint8_t i = 0; i < 3; i++) {uint8_t pos = (position + i) % LED_NUMBER;keyboard.SetRgbBuffer(pos, {0, 0, 255 - i*50});}// 移动位置position = (position + 1) % LED_NUMBER;// 更新LED显示keyboard.SyncLights();
}// 步骤2:在main循环中调用自定义灯效
int main(void)
{// 初始化代码...while (1){// 处理按键...// 调用自定义灯效MyCustomEffect();// 其他任务...}
}
扩展思路:
- 可以创建灯效库,通过自定义按键切换不同灯效
- 为特定按键设置独特颜色,如WASD按键高亮
- 实现与按键反馈联动的灯效,如按下按键时产生涟漪效果
4.5 Dynamic模块APP开发
// 步骤1:在Dynamic-fw中创建新的APP类
class MyCustomApp : public AppBase
{
public:MyCustomApp() {// 初始化}// 绘制墨水屏内容void renderEPaper() override {ePaper.clearBuffer();ePaper.setFont(u8g2_font_ncenB14_tr);ePaper.drawStr(10, 32, "My Custom App");// 绘制更多内容...ePaper.sendBuffer();}// 处理旋钮事件void onEncoderRotate(int16_t delta) override {// 根据旋转方向和幅度响应if (delta > 0) {// 顺时针旋转value += delta;} else {// 逆时针旋转value -= -delta;}// 设置力反馈float torque = sin(value * 0.1) * 0.5;motor->setTorque(torque);}// 处理按钮事件void onButtonPress(uint8_t buttonId) override {// 处理按钮按下事件}private:int value = 0;
};// 步骤2:注册APP到系统
void initApps()
{// 注册已有APPappsManager.registerApp(new ClockApp());appsManager.registerApp(new VolumeControlApp());// 注册自定义APPappsManager.registerApp(new MyCustomApp());
}
开发建议:
- 研究现有APP的实现逻辑,掌握系统架构
- 墨水屏更新要谨慎,频繁刷新会导致闪烁和老化
- 力反馈建议使用自然的物理模型,如弹簧、阻尼等,提升用户体验
五、常见问题及解决方案
5.1 硬件问题
Q1: 按键无响应或错误触发?
A1: - 检查74HC165芯片连接是否正确- 验证焊接质量,排除虚焊问题- 检查按键是否正确安装到PCB上- 修改滤波时间参数,延长去抖时间Q2: RGB灯不亮或显示错误?
A2: - 检查WS2812B灯珠焊接方向是否正确- 验证SPI配置,确保时钟频率合适(通常8MHz)- 检查数据线连接是否完好- 通过逐一点亮测试排查问题灯珠Q3: 力反馈旋钮不工作?
A3: - 确认电机和编码器正确安装- 测量电机驱动电路工作电压是否正常- 尝试运行提供的测试固件,执行电机校准- 检查FPC线缆质量,长度过长会导致压降
5.2 软件问题
Q1: 编译错误怎么解决?
A1: - 检查开发环境配置,确保安装了正确版本的工具链- 验证所有依赖库是否正确包含- 检查项目配置中的芯片型号是否与实际使用的匹配- 查看错误日志,针对具体问题解决Q2: 按键映射不正确?
A2: - 重新检查第0层映射与物理按键的对应关系- 打印扫描结果,确认每个按键被正确识别- 确保keyMap数组维度与实际按键数匹配- 验证多层映射逻辑是否正确Q3: 墨水屏无法更新?
A3: - 检查SPI通信配置- 验证墨水屏型号与驱动代码是否匹配- 墨水屏可能需要上电重置,尝试重启设备- 检查图像数据格式是否符合要求
六、项目拓展思路
6.1 功能拓展方向
1. 网络连接能力- 添加ESP32模块实现Wi-Fi连接- 开发云端配置和同步功能- 实现IoT控制功能2. 高级输入体验- 添加热插拔支持- 实现压力感应按键- 添加触摸条或触摸板3. 软件生态- 开发跨平台配置软件- 建立用户分享键位配置的平台- 开发Dynamic模块的APP商店
6.2 硬件升级路线
1. 主控升级- 使用STM32F4/F7系列获得更强性能- 添加蓝牙连接模块实现无线功能- 增加内存和存储空间支持更多功能2. 显示升级- 更换为彩色LCD或AMOLED屏幕- 添加更多显示区域- 实现动态UI界面3. 传感器增强- 添加环境光传感器自动调节RGB亮度- 集成IMU实现手势控制- 添加指纹识别增强安全性
七、总结
瀚文(HelloWord)键盘项目是一个集硬件设计、固件开发、结构设计于一体的综合性项目,其模块化的设计理念和创新的技术实现使其成为DIY键盘领域的杰出案例。无论你是硬件爱好者、嵌入式开发者还是普通用户,都能从这个项目中获取有价值的知识和灵感。
通过本文的详细解析,希望能帮助你从0开始理解瀚文键盘的设计理念和技术实现,进而定制或开发出属于自己的智能键盘。开源精神的核心就是分享和创新,期待看到更多基于瀚文的创意项目!
本文档基于瀚文键盘开源项目分析整理,项目地址:HelloWord-Keyboard
相关文章:
瀚文(HelloWord)智能键盘项目深度剖析:从0到1的全流程解读
瀚文(HelloWord)智能键盘项目深度剖析:从0到1的全流程解读 一、项目整体概述 瀚文(HelloWord)智能键盘是一款多功能、模块化的智能机械键盘,由三大部分组成:键盘输入模块、可替换的多功能交互…...
Shell编程核心符号与格式化操作详解
Shell编程作为Linux系统管理和自动化运维的核心技能,掌握其常用符号和格式化操作是提升脚本开发效率的关键。本文将深入解析Shell中重定向、管道符、EOF、输入输出格式化等核心概念,并通过丰富的实践案例帮助读者掌握这些重要技能。 一、信息传递与重定…...
针对“仅某个地区出现Bug”的原因分析与解决方案
一、核心排查方向(按优先级排序) 地区相关配置差异 检查点: 该地区是否有独立的配置文件或数据库分片?是否启用了地区特定的功能开关(Feature Flag)或AB测试?本地化内容(如语言、时…...

学习STC51单片机30(芯片为STC89C52RCRC)
每日一言 当你感到疲惫时,正是成长的关键时刻,再坚持一下。 IIC协议 是的,IIC协议就是与我们之前的串口通信协议是同一个性质,就是为了满足模块的通信,其实之前的串口通信协议叫做UART协议,我们千万不要弄…...
sql中group by使用场景
GROUP BY语句在SQL中用于将多个记录分组为较小的记录集合,以便对每个组执行聚合函数,如COUNT(), MAX(), MIN(), SUM(), AVG()等。GROUP BY的使用场景非常广泛,以下是一些典型的应用场景: 统计数量 当你想要计算某个字段的唯一值数…...
将HTML内容转换为Canvas图像,主流方法有效防止文本复制
HTML to Canvas 使用说明 项目概述 此项目实现了将HTML内容转换为Canvas图像的功能,可有效防止文本被复制。适用于需要保护内容的场景,如试题系统、付费内容等。 主要功能 防止复制: 将文本内容转换为Canvas图像,使用户无法选择和复制Mat…...

Python-进程
进程 简介 操作系统分配资源的基本单位 创建 依赖 依赖模块 multiprocessing 中的 Process 语法 Process(group[,target[,name[,args[,kwargs]]]]) target:如果传递了函数的引用,这个子进程就执行这里的代码args:元组的方式传递&#x…...

Paraformer分角色语音识别-中文-通用 FunASR demo测试与训练
文章目录 0 资料1 Paraformer分角色语音识别-中文-通用1 模型下载2 音频识别测试3 FunASR安装 (训练用)4 训练 0 资料 https://github.com/modelscope/FunASR/blob/main/README_zh.md https://github.com/modelscope/FunASR/blob/main/model_zoo/readm…...
【从0-1的CSS】第1篇:CSS简介,选择器以及常用样式
文章目录 CSS简介CSS的语法规则选择器id选择器元素选择器类选择器选择器优先级 CSS注释 CSS常用设置样式颜色颜色名称(常用)RGB(常用)RGBA(常用)HEX(常用)HSLHSLA 背景background-colorbackground-imagebackground-size 字体text-aligntext-decorationtext-indentline-height 边…...

对抗反爬机制的分布式爬虫自适应策略:基于强化学习的攻防博弈建模
在大数据时代,数据的价值不言而喻。网络爬虫作为获取数据的重要工具,被广泛应用于各个领域。然而,随着爬虫技术的普及,网站为了保护自身数据安全和服务器性能,纷纷采取了各种反爬机制。这就使得爬虫与反爬虫之间形成了…...
JDK21深度解密 Day 15:JDK21实战最佳实践总结
【JDK21深度解密 Day 15】JDK21实战最佳实践总结 文章简述 本篇文章是《JDK21深度解密:从新特性到生产实践的全栈指南》系列的第15篇,聚焦于JDK21实战最佳实践总结。作为Java历史上最重要的LTS版本之一,JDK21带来了虚拟线程、结构化并发、模式匹配、ZGC优化等革命性特性,…...

手写muduo网络库(一):项目构建和时间戳、日志库
引言 本文作为手写 muduo 网络库系列开篇,聚焦项目基础框架搭建与核心基础工具模块设计。通过解析 CMake 工程结构设计、目录规划原则,结合时间戳与日志系统的架构,为后续网络库开发奠定工程化基础。文中附完整 CMake 配置示例及模块代码。 …...
每日算法刷题Day25 6.7:leetcode二分答案3道题,用时1h40min(遇到两道动态规划和贪心时间较长)
3. 1631.最小体力消耗路径(中等,dfs不熟练) 1631. 最小体力消耗路径 - 力扣(LeetCode) 思想 1.你准备参加一场远足活动。给你一个二维 rows x columns 的地图 heights ,其中 heights[row][col] 表示格子 (row, col) 的高度。一开始你在最左…...

14-Oracle 23ai Vector Search 向量索引和混合索引-实操
一、Oracle 23ai支持的2种主要的向量索引类型: 1.1 内存中的邻居图向量索引 (In-Memory Neighbor Graph Vector Index) HNSW(Hierarchical Navigable Small World :分层可导航小世界)索引 是 Oracle AI Vector Search 中唯一支持的内存邻居图向量索引类…...
kubeadm安装k8s
1、环境准备 1.1、升级系统内核 参考另一篇文章:https://blog.csdn.net/u012533920/article/details/148457715?spm1011.2415.3001.5331 1.2、设置Hostname cat <<EOF > /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhos…...
服务器新建用户无法使用conda
服务器新建用户无法使用conda 1.将.bashrc文件复制到新用户家目录下 sudo cp .bashrc /home/newuser/.bashrc2.source命令激活该文件 source ~/.bashrc3.将.condarc文件复制到新用户家目录下 sudo cp .condarc/home/newuser/.condarc...

Web前端基础:JavaScript
1.JS核心语法 1.1 JS引入方式 第一种方式:内部脚本,将JS代码定义在HTML页面中 JavaScript代码必须位于<script></script>标签之间在HTML文档中,可以在任意地方,放置任意数量的<script></script>一般会把…...
基于对比学习的带钢表面缺陷分类研究,整合SimCLR自监督预训练与YOLOv8目标检测框架的技术解析及Python实现方案
以下基于对比学习的带钢表面缺陷分类研究,整合SimCLR自监督预训练与YOLOv8目标检测框架的技术解析及Python实现方案: 基于对比学习的带钢表面缺陷分类研究 ——SimCLR与YOLOv8算法融合应用 #mermaid-svg-VqDPIOfR5WJcGtD7 {font-family:"trebuchet ms",verdana,ar…...

基于AWS Serverless架构:零运维构建自动化SEO内容生成系统
作者:[Allen] 技术专栏 | 深度解析云原生SEO自动化 在流量为王的时代,持续产出高质量SEO内容成为技术运营的核心痛点。传统方案面临开发成本高、扩展性差、关键词响应滞后三大难题。本文将分享如何用AWS Serverless技术栈,构建一套零服务器运…...
【.net core】天地图坐标转换为高德地图坐标(WGS84 坐标转 GCJ02 坐标)
类文件 public static class WGS84ToGCJ02Helper {// 定义一些常量private const double PI 3.14159265358979324;private const double A 6378245.0;private const double EE 0.00669342162296594323;// 判断坐标是否在中国范围内(不在国内则不进行转换&#x…...
Linux操作系统故障应急场景及对应排查方法
001:系统CPU负载高并触发监控报警 005 查看系统CPU使用情况,,确认CPU数量,确认系统负载,确认CPU高对系统的影响 006 定位占用CPU资源最多的进程,根据进程判断是应用进程还是系统进程还是第三方工具进程。 014 查看…...

电镀机的阳极是什么材质?
知识星球(星球名:芯片制造与封测技术社区,点击加入)里的学员问:电镀的阳极有什么讲究?什么是可溶性阳极和非可溶性阳极? 什么是可溶性阳极与非可溶性阳极? 可溶性阳极 阳极本身就是…...

vscode调试deepspeed的方法之一(无需调整脚本)
现在deepspeed的脚本文件是: # 因为使用 RTX 4000 系列显卡时,不支持通过 P2P 或 IB 实现更快的通信宽带,需要设置以下两个环境变量 # 禁用 NCCL 的 P2P 通信,以避免可能出现的兼容性问题 export NCCL_P2P_DISABLE"1" …...
神经网络-Day44
import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pyplot as plt# 设置中文字体支持 plt.rcParams["font.family"] ["SimHei"…...
创客匠人:如何通过精准定位实现创始人IP打造与知识变现
在当今知识经济时代,越来越多的专业人士希望通过个人品牌实现知识变现,但许多人面临一个共同困境:明明很努力,却收效甚微。创客匠人作为深耕知识付费赛道9年的专业机构,揭示了这一现象背后的关键原因——90%的IP失败源…...

Codeforces Round 509 (Div. 2) C. Coffee Break
题目大意: 给你n、m、d n为元素个数,m为数列长度,d为每个元素之间的最短间隔 问最少需要多少个数列可以使得元素都能装进数列,并且满足每个元素之间的间隔大于等于d 核心思想 使用贪心的思想,将元素的大小进行排序,问题出在必…...

榕壹云健身预约系统:多门店管理的数字化解决方案(ThinkPHP+MySQL+UniApp实现)
随着全民健身热潮的兴起,传统健身房在会员管理、课程预约、多门店运营等方面面临诸多挑战。针对这一需求,我们开发了一款基于ThinkPHPMySQLUniApp的榕壹云健身预约系统,为中小型健身机构及连锁品牌提供高效、灵活的数字化管理工具。本文将详细…...

QUIC——UDP实现可靠性传输
首先我们要知道TCP存在什么样的痛点问题 TCP的升级很困难TCP建立连接的延迟网络迁移需要重新建立连接TCP存在队头阻塞问题 QUIC就是为了解决以上的问题而诞生了, 下面我会介绍QUIC的一些特性和原理 QUIC对比TCP优势: 握手建连更快 QUIC内部包含了TLS, 它在自己的帧会携带TL…...
提高Python编程效率的工具推荐
在 Python 开发中,选择合适的工具可以显著提升编程效率。以下是一些经过精心挑选的工具,涵盖代码编辑、调试、数据分析等多个方面,希望能帮助你在 Python 开发中事半功倍。 一、集成开发环境(IDE) 1. PyCharm PyCha…...
React Native图片预加载:让你的应用图片预览像德芙一样丝滑
写在前面:一张图片引发的性能血案 你有没有遇到过这种情况?——用户疯狂滑动你的React Native图片列表,结果图片加载慢得像蜗牛,甚至出现空白闪烁?等到图片终于加载出来,用户早就失去耐心,愤然退出…… 但你知道吗?这个问题只需要几行代码就能解决! 比如,使用reac…...