网站的制作步骤包括/百度域名收录
虽然选择了触摸屏,我仍选择为机械键盘嵌入摇杆模块,这本质上是对"操作连续性"的执着。
值得深思的是,本次开发过程中借助DeepSeek的代码生成与逻辑推理,其展现的能力已然颠覆传统编程范式,需求描述可自动转化为功能实现,算法优化能自主完成多目标博弈,这昭示着技术生产关系的根本性变革。
技术演进正在重构价值坐标系,边缘计算设备通过蒸馏更好的模型实现端侧智能,使AI能力呈指数级渗透产业格局,算力资本形成的新型生产资料,正在重塑技术话语权分配机制,工程师的核心竞争力将从代码实现转向需求抽象、系统架构与伦理把控在这场人机协同的认知革命,真正的危机并非技术替代,而是思维范式的停滞。
当AI解构了执行层的技术壁垒,人类智慧的战场必将向更高维度迁移——那些涉及跨领域创新、价值判断与复杂系统设计的领域,正是技术人亟待开垦的新边疆,但愿技术人可以在这样的狭缝中获得存在的意义。
言归正传还是回到我们的QMK键盘增加摇杆功能,首先要了解一下QMK 生成键盘的整体文件结构:
qmk_firmware/keyboards/demo_keyboard/
├── config.h
├── keymaps/
│ └── default/
│ ├── keymap.c
├── rules.mk
└── keyboard.json
keyboard.json功能:定义键盘的硬件配置、布局、功能和元数据。示例
rules.mk功能:定义编译选项和功能开关。
config.h功能:定义键盘的硬件配置和宏。
keymaps/default/keymap.c功能:定义默认键位布局,开启自定义功能。
所以增加摇杆和鼠标就需要在这些文件里面进行修改
在rules.mk中启用摇杆和鼠标按键功能
POINTING_DEVICE_ENABLE = yes
POINTING_DEVICE_DRIVER = analog_joystick
MOUSEKEY_ENABLE = yes
# DEBUG_ENABLE = yes
# CONSOLE_ENABLE = yes # 启用调试输出
在config.h中添加摇杆和鼠标键的读取对应端口
/*
Copyright 2025 <JohnsonLv>This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/#pragma once#define ANALOG_JOYSTICK_X_AXIS_PIN GP26
#define ANALOG_JOYSTICK_Y_AXIS_PIN GP27
#define MOUSE_BTN1_PIN GP15
在keymap.c中添加,保留以前的键盘键的映射,然后添加一些关于摇杆的函数
/// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later#pragma once#include QMK_KEYBOARD_H
#include "pointing_device.h"
#include "print.h"
#include "timer.h" // 用于 timer_read32 和 timer_elapsed32// 定义摇杆的灵敏度
#define JOYSTICK_SENSITIVITY 1static bool debounce = false;
static uint32_t debounce_timer = 0;// 初始化独立按键的 GPIO
void keyboard_post_init_user(void) {setPinInputHigh(MOUSE_BTN1_PIN); // 设置为输入模式,启用内部上拉电阻
}// 新增参数定义(需根据实际需求调整)
#define MAX_CURSOR_SPEED 10 // 最大光标速度
#define SPEED_REGULATOR 3 // 速度调节系数// 非线性映射函数(基于 IBM 专利逻辑)
void joystick_ibm_algorithm(int16_t x, int16_t y, int16_t* x_out, int16_t* y_out) {static int16_t z_prev = 0; // 静态变量保存上一次的 z 值// --- 核心算法逻辑 ---// 1. 计算近似平方根的 z 值int16_t ax = abs(x);int16_t ay = abs(y);int16_t z = ax + ay - ((2 * (ax < ay ? ax : ay)) / 3);// 2. 动态调整光标移动if (z > 4) {// 计算动态变化的 zi 值(包含释放补偿)int16_t zi = (z - z_prev) * 6 + z;// 计算最终坐标(避免除以零)int16_t x_calc = (zi == 0) ? 0 : (x * z * MAX_CURSOR_SPEED) / (zi * SPEED_REGULATOR);int16_t y_calc = (zi == 0) ? 0 : (y * z * MAX_CURSOR_SPEED) / (zi * SPEED_REGULATOR);*x_out = x_calc;*y_out = y_calc;} else {*x_out = 0;*y_out = 0;}// 3. 保存当前 z 值供下次使用z_prev = z;
}// 处理独立按键和摇杆的函数
void my_process_joystick(void) {// 获取摇杆的 X/Y 轴值int16_t x_raw= joystick_state.axes[0];int16_t y_raw= joystick_state.axes[1];// 创建鼠标报告report_mouse_t mouse_report = {0};// 应用 IBM 算法int16_t x_mapped, y_mapped;joystick_ibm_algorithm(x_raw, y_raw, &x_mapped, &y_mapped);// 检测独立按键状态(按下时为低电平)bool btn_state = !readPin(MOUSE_BTN1_PIN); // 按下时为 true// 消抖逻辑if (btn_state && !debounce) {debounce = true;debounce_timer = timer_read32();mouse_report.buttons |= KC_BTN1; // 触发左键} else if (!btn_state && debounce) {if (timer_elapsed32(debounce_timer) > 5) { // 消抖时间 5msdebounce = false;mouse_report.buttons &= ~KC_BTN1; // 释放左键}}// 发送鼠标报告pointing_device_set_report(mouse_report);pointing_device_send();
}// 键盘矩阵扫描后的钩子函数
void matrix_scan_user(void) {my_process_joystick();
}// 键盘布局定义(无需为独立按键分配矩阵键位)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {[0] = LAYOUT_numpad_4x4(KC_1, KC_2, KC_3, KC_4,KC_5, KC_6, KC_7, KC_8,KC_9, KC_0, KC_A, KC_B,KC_C, KC_D, KC_BTN2, KC_BTN3 // 保持矩阵中的键位不变)
};
在上面的这段算法中借用了 https://patents.google.com/patent/US5570111A, IBM的一个专利技术
以下是这段基于 IBM 专利的摇杆算法的逐层解析,我将用 「物理直觉 → 数学实现 → 代码表达」 的逻辑链解释其精妙之处:
1. 近似矢量长度(模拟平方根)物理需求:
需要计算摇杆偏移的「矢量长度」,但避免耗时的真实平方根运算。数学实现:
通过线性组合近似替代 x 2 + y 2 \sqrt{x² + y²} x2+y2,专利给出的公式: z = ∣ x ∣ + ∣ y ∣ − ( 2 ∗ m i n ( ∣ x ∣ , ∣ y ∣ ) ) / 3 z = |x| + |y| - (2 * min(|x|, |y|)) / 3 z=∣x∣+∣y∣−(2∗min(∣x∣,∣y∣))/3
代码实现:
int16_t ax = abs(x);
int16_t ay = abs(y);
int16_t z = ax + ay - ((2 * (ax < ay ? ax : ay)) / 3);
效果说明:当摇杆沿对角线移动时(x=y),公式简化为 ( 4 / 3 ) ∗ x (4/3) * x (4/3)∗x,接近真实平方根 2 ∗ x ≈ 1.414 x \sqrt2*x ≈ 1.414x 2∗x≈1.414x当摇杆沿单轴移动时(如 x=0),公式退化为 y,与真实值一致平衡了计算效率和准确性
2. 动态响应补偿(预测释放动作)
物理需求:
当用户松开摇杆时,光标会因惯性继续移动,需要模拟「减速回弹」效果。
数学实现:
通过差分计算摇杆速度变化:
z i = z + 6 ∗ ( z − z p r e v ) zi = z + 6*(z - z_{prev}) zi=z+6∗(z−zprev)
( z p r e v z_{prev} zprev是上一帧的 z 值)
代码实现:
int16_t zi = (z - z_prev) * 6 + z; // 放大变化量的影响
效果说明:
- 快速释放时(z 急剧减小): z i zi zi会远小于 z z z,导致 x c a l c / y c a l c x_{calc}/y_{calc} xcalc/ycalc分母增大,光标减速
- 保持摇杆时(z 稳定): z i ≈ z zi ≈ z zi≈z,光标匀速移动
- 推动摇杆时(z 增大): z i > z zi > z zi>z,分母增大,光标加速更平缓
3. 非线性速度映射
物理需求:
摇杆偏移量与光标速度呈非线性关系(小偏移精细控制,大偏移快速移动)。
数学实现:
速度公式:
x_calc = (x * z * MAX_CURSOR_SPEED) / (zi * SPEED_REGULATOR)
代码实现:
int16_t x_calc = (zi == 0) ? 0 : (x * z * MAX_CURSOR_SPEED) / (zi * SPEED_REGULATOR);
参数控制:
参数 | 作用 | 调整建议 |
---|---|---|
MAX_CURSOR_SPEED | 最大移动速度 | 值越大光标移动越快 |
SPEED_REGULATOR | 整体灵敏度调节 | 值越大光标移动越慢 |
6 (zi的系数) | 惯性响应强度 | 值越大释放时的减速越明显 |
4. 死区处理与噪声过滤
物理需求:
消除摇杆中心位置的微小抖动。
数学实现:
当 z ≤ 4
时强制归零:
if (z > 4) { ... } else { *x_out=0; *y_out=0; }
效果说明:
- 过滤摇杆电阻器的噪声
- 提供明确的中心死区
整体算法流程图
原始输入 (x,y) ↓
计算近似矢量长度 z ↓
动态补偿 → 计算 zi (包含惯性预测) ↓
非线性映射 → 输出 (x_calc, y_calc) ↓
保存 z 值 → 供下一帧使用
实际调试技巧
-
参数联动调整:
- 先固定
SPEED_REGULATOR=1
,调整MAX_CURSOR_SPEED
确定最大速度 - 然后增大
SPEED_REGULATOR
微调灵敏度 - 最后调整
zi
的系数(代码中的6
)控制惯性效果
- 先固定
-
边界保护:
添加范围限制防止溢出:
x_calc = MAX(-127, MIN(x_calc, 127)); // 确保在鼠标协议范围内
这个算法通过巧妙的近似和差分计算,在极低的计算开销下实现了符合人体工学的光标控制特性,正是这种「用简单数学模拟复杂物理直觉」的设计,让它成为经典。
相关文章:

QMK启用摇杆和鼠标按键功能
虽然选择了触摸屏,我仍选择为机械键盘嵌入摇杆模块,这本质上是对"操作连续性"的执着。 值得深思的是,本次开发过程中借助DeepSeek的代码生成与逻辑推理,其展现的能力已然颠覆传统编程范式,需求描述可自动…...

Unity实现按键设置功能代码
一、前言 最近在学习unity2D,想做一个横版过关游戏,需要按键设置功能,让用户可以自定义方向键与攻击键等。 自己写了一个,总结如下。 二、界面效果图 这个是一个csv文件,准备第一列是中文按键说明,第二列…...

基于物联网技术的实时数据流可视化研究(论文+源码)
1系统方案设计 根据系统功能的设计要求,展开基于物联网技术的实时数据流可视化研究设计。如图2.1所示为系统总体设计框图,系统以STM32单片机做为主控制器,通过DHT11、MQ-2、光照传感器实现环境中温湿度、烟雾、光照强度数据的实时检测&#x…...

list容器(详解)
1. list的介绍及使用 1.1 list的介绍(双向循环链表) https://cplusplus.com/reference/list/list/?kwlist(list文档介绍) 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭…...

Elasticsearch基本使用详解
文章目录 Elasticsearch基本使用详解一、引言二、环境搭建1、安装 Elasticsearch2、安装 Kibana(可选) 三、索引操作1、创建索引2、查看索引3、删除索引 四、数据操作1、插入数据2、查询数据(1)简单查询(2)…...

17.3.4 颜色矩阵
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 17.3.4.1 矩阵基本概念 矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,类似于数组。 由…...

FPGA 时钟多路复用
时钟多路复用 您可以使用并行和级联 BUFGCTRL 的组合构建时钟多路复用器。布局器基于时钟缓存 site 位置可用性查找最佳布局。 如果可能,布局器将 BUFGCTRL 布局在相邻 site 位置中以利用专用级联路径。如无法实现,则布局器将尝试将 BUFGCTRL 从…...

机器学习10
自定义数据集 使用scikit-learn中svm的包实现svm分类 代码 import numpy as np import matplotlib.pyplot as pltclass1_points np.array([[1.9, 1.2],[1.5, 2.1],[1.9, 0.5],[1.5, 0.9],[0.9, 1.2],[1.1, 1.7],[1.4, 1.1]])class2_points np.array([[3.2, 3.2],[3.7, 2.9],…...

【Block总结】CoT,上下文Transformer注意力|即插即用
一. 论文信息 标题: Contextual Transformer Networks for Visual Recognition论文链接: arXivGitHub链接: https://github.com/JDAI-CV/CoTNet 二. 创新点 上下文Transformer模块(CoT): 提出了CoT模块,能够有效利用输入键之间的上下文信息…...

linux库函数 gettimeofday() localtime的概念和使用案例
在Linux系统中,gettimeofday() 和 localtime() 是两个常用的时间处理函数,分别用于获取高精度时间戳和将时间戳转换为本地时间。以下是它们的概念和使用案例的详细说明: 1. gettimeofday() 函数 概念 功能:获取当前时间…...

编程题-电话号码的字母组合(中等)
题目: 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 解法一(哈希表动态添加)&#x…...

EasyExcel使用详解
文章目录 EasyExcel使用详解一、引言二、环境准备与基础配置1、添加依赖2、定义实体类 三、Excel 读取详解1、基础读取2、自定义监听器3、多 Sheet 处理 四、Excel 写入详解1、基础写入2、动态列与复杂表头3、样式与模板填充 五、总结 EasyExcel使用详解 一、引言 EasyExcel 是…...

基于“蘑菇书”的强化学习知识点(二):强化学习中基于策略(Policy-Based)和基于价值(Value-Based)方法的区别
强化学习中基于策略(Policy-Based)和基于价值(Value-Based)方法的区别 摘要强化学习中基于策略(Policy-Based)和基于价值(Value-Based)方法的区别1. 定义与核心思想(1) 基于策略的方…...

民法学学习笔记(个人向) Part.2
民法学学习笔记(个人向) Part.2 民法始终在解决两个生活中的核心问题: 私法自治;交易安全; 3. 自然人 3.4 个体工商户、农村承包经营户 都是特殊的个体经济单位; 3.4.1 个体工商户 是指在法律的允许范围内,依法经…...

物业管理系统源码驱动社区管理革新提升用户满意度与服务效率
内容概要 在当今社会,物业管理正面临着前所未有的挑战,尤其是在社区管理方面。人们对社区安全、环境卫生、设施维护等日常生活需求愈发重视,物业公司必须提升服务质量,以满足居民日益增长的期望。而物业管理系统源码的出现&#…...

租房管理系统助力数字化转型提升租赁服务质量与用户体验
内容概要 随着信息技术的快速发展,租房管理系统正逐渐成为租赁行业数字化转型的核心工具。通过全面集成资产管理、租赁管理和物业管理等功能,这种系统力求为用户提供高效便捷的服务体验。无论是工业园、产业园还是写字楼、公寓,租房管理系统…...

Ollama教程:轻松上手本地大语言模型部署
Ollama教程:轻松上手本地大语言模型部署 在大语言模型(LLM)飞速发展的今天,越来越多的开发者希望能够在本地部署和使用这些模型,以便更好地控制数据隐私和计算资源。Ollama作为一个开源工具,旨在简化大语言…...

Baklib推动数字化内容管理解决方案助力企业数字化转型
内容概要 在当今信息爆炸的时代,数字化内容管理成为企业提升效率和竞争力的关键。企业在面对大量数据时,如何高效地存储、分类与检索信息,直接关系到其经营的成败。数字化内容管理不仅限于简单的文档存储,更是整合了文档、图像、…...

DeepSeek-R1 论文. Reinforcement Learning 通过强化学习激励大型语言模型的推理能力
论文链接: [2501.12948] DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning 实在太长,自行扔到 Model 里,去翻译去提问吧。 工作原理: 主要技术,就是训练出一些专有用途小模型&…...

DOM 操作入门:HTML 元素操作与页面事件处理
DOM 操作入门:HTML 元素操作与页面事件处理 DOM 操作入门:HTML 元素操作与页面事件处理什么是 DOM?1. 如何操作 HTML 元素?1.1 使用 `document.getElementById()` 获取单个元素1.2 使用 `document.querySelector()` 和 `document.querySelectorAll()` 获取多个元素1.3 创建…...

使用 HTTP::Server::Simple 实现轻量级 HTTP 服务器
在Perl中,HTTP::Server::Simple 模块提供了一种轻量级的方式来实现HTTP服务器。该模块简单易用,适合快速开发和测试HTTP服务。本文将详细介绍如何使用 HTTP::Server::Simple 模块创建和配置一个轻量级HTTP服务器。 安装 HTTP::Server::Simple 首先&…...

C++滑动窗口技术深度解析:核心原理、高效实现与高阶应用实践
目录 一、滑动窗口的核心原理 二、滑动窗口的两种类型 1. 固定大小的窗口 2. 可变大小的窗口 三、实现细节与关键点 1. 窗口的初始化 2. 窗口的移动策略 3. 结果的更新时机 四、经典问题与代码示例 示例 1:和 ≥ target 的最短子数组(可变窗口…...

基于构件的软件开发方法
摘要: 本人在2023年1月参与广东某公司委托我司开发的“虚拟电厂”项目,主要负责整体架构设计和中间件的选型,该项目为新型电力存储、电力调度、能源交易提供一整套的软件系统,包括设备接入、负载预测、邀约竞价、用户设备调控等功能。本项目以“虚拟电厂”项目为例,讨论基…...

网站快速收录:如何设置robots.txt文件?
本文转自:百万收录网 原文链接:https://www.baiwanshoulu.com/34.html 为了网站快速收录而合理设置robots.txt文件,需要遵循一定的规则和最佳实践。robots.txt文件是一个纯文本文件,它告诉搜索引擎爬虫哪些页面可以访问ÿ…...

OpenGL学习笔记(六):Transformations 变换(变换矩阵、坐标系统、GLM库应用)
文章目录 向量变换使用GLM变换(缩放、旋转、位移)将变换矩阵传递给着色器坐标系统与MVP矩阵三维变换绘制3D立方体 & 深度测试(Z-buffer)练习1——更多立方体 现在我们已经知道了如何创建一个物体、着色、加入纹理。但它们都还…...

8.攻防世界Web_php_wrong_nginx_config
进入题目页面如下 尝试弱口令密码登录 一直显示网站建设中,尝试无果,查看源码也没有什么特别漏洞存在 用Kali中的dirsearch扫描根目录试试 命令: dirsearch -u http://61.147.171.105:53736/ -e* 登录文件便是刚才登录的界面打开robots.txt…...

【优先算法】专题——位运算
在讲解位运算之前我们来总结一下常见的位运算 一、常见的位运算 1.基础为运算 << &:有0就是0 >> |:有1就是1 ~ ^:相同为0,相异位1 /无进位相加 2.给一个数 n,确定它的二进制表示…...

qt.qpa.plugin: Could not find the Qt platform plugin “dxcb“ in ““
个人博客地址:qt.qpa.plugin: Could not find the Qt platform plugin "dxcb" in "" | 一张假钞的真实世界 我遇到的场景是,在Deepin系统终端中运行PySide应用时,没有错误提示,但在VS Code中运行时ÿ…...

1-刷力扣问题记录
25.1.19 1.size()和.length()有什么区别 2.result.push_back({nums[i], nums[left], nums[right]});为什么用大括号? 使用大括号 {} 是 C11 引入的 初始化列表 语法,它允许我们在构造或初始化对象时直接传入一组值。大括号的使用在许多情况下都能让代码…...

物联网 STM32【源代码形式-使用以太网】连接OneNet IOT从云产品开发到底层MQTT实现,APP控制 【保姆级零基础搭建】
物联网(IoT)是指通过各种信息传感器、射频识别技术、全球定位系统、红外感应器等装置与技术,实时采集并连接任何需要监控、连接、互动的物体或过程,实现对物品和过程的智能化感知、识别和管理。物联网的核心功能包括数据采集与监…...