Zephyr255 发布的文章

化学第四小考,极不称意;平生考试,此为最下。打牌。⸺胡适全集 第 27 卷量子力学学到现在深感无力,直呼不可理解,遂记此笔记以期整理思绪。基础狄拉克记号 (bra-ket notation)维基百科已经解释得很好了,在此直接引用:狄拉克符号或狄拉克标记 (Dirac notation) 是量子力学中广泛应用于描述量子态的一套标准符号系统。在这套系统中,每一个量子态都被描述为希尔伯特空间中的态矢量,定义为右矢 (ket):$| \psi \rangle$;每一个右矢的共轭转置定义为其左矢 (bra): $\langle \psi |$;换一种说法,右矢的厄米共轭(即取转置运算加上共轭复数运算),就可以得到左矢。简单地解释一下定义中的专业名词:量子态 (quantum state) 指量子系统的状态。态矢量 (state vector) 可以用于抽象地表示一个量子系统的状态。态矢量是希尔伯特空间中的一个矢量。希尔伯特空间即为完备的内积空间,其维数由其描述的物理系统定义。两个态矢量 $|\pm \psi \rangle$ 在二维的 1/2 自旋系统中构成一组基,其满足三条基本属性:$|+\rangle \cdot |+\rangle = 1$$|+\rangle \cdot |-\rangle = 0$$|\psi\rangle = a|+\rangle +b|-\rangle$通过厄米转置 (Hermitian conjugate,亦称埃尔米特转置) 可将右矢变换为左矢:若 $|\psi\rangle = a|+\rangle + b|+\rangle$,则 $\langle\psi| = a^\ast\langle+| + b^\ast\langle-|$量子力学中的内积之定义为左矢与右矢之积 $\langle\psi|\psi\rangle$符号之外,量子力学还有一套重要的基本公设:一个量子力学系统之状态(包括了其所有的可知性质)可在数学上使用归一化过的右矢 $|\psi\rangle$ 表示。一个物理可观测量由可作用于右矢上的算符 $A$ 表示。对某个可观测量的测量结果只可能是与其相对应的算符 $A$ 的一个特征值 $a_n$在对处于量子态 $|\psi\rangle$ 的系统的可观测量 $A$ 作测量时,得到结果 $a_n$ 的可能性是 $P_{a_n} = |\langle a_n|\psi\rangle|^2$,其中 $|a_n\rangle$ 为 $a_n$ 对应的归一化处理后的特征向量。测量 $A$ 得到结果 $a_n$ 后,该系统的量子态变为原系统之右矢在测量结果对应的右矢上的归一化投影:$$|\psi\rangle = \frac{P_n|\psi\rangle}{\sqrt{\langle \psi|P_n|\psi\rangle}}$$量子力学系统的时间演化可以由将其汉密顿量(或总能量)算子带入薛定谔方程得出:$$i\hbar\frac{d}{dt}|\psi\rangle=H(t)|\psi(t)\rangle$$不要恐慌!看不懂其中的专有名词是正常的,在接下来的章节中我们会慢慢解释它们的意义。矩阵表述使用上述的内容,我们唯一的描述矢的方法,便是使用其与其它矢的内积:$|\psi\rangle = \langle +|\psi\rangle|+\rangle+\langle-|\psi\rangle|-\rangle$于是 $|+\rangle_x$ 可以描述为 $|+\rangle_x=\langle + |+\rangle_x|+\rangle +\langle-|+\rangle_x|-\rangle = {1\over\sqrt{2}}|+\rangle+{1\over\sqrt{2}}|-\rangle$也就是说,只要选定一对基(即上述例子中的 $|+\rangle$ 和 $|-\rangle$,我们便可以用一对系数来描述一个量子态,例如上述的 $|+\rangle_x$ 可以写作 ${1\over\sqrt{2}}\begin{pmatrix}1\\1\end{pmatrix}$,而任意量子态 $|\psi\rangle$ 则可用 $\begin{pmatrix}\langle+|\psi\rangle\\ \langle-|\psi\rangle\end{pmatrix}$ 写成矩阵形式。为了符合矩阵运算法则,左矢可以写成右矢的共轭转置,即右矢 $|\psi\rangle=\begin{pmatrix}a\\b\end{pmatrix}$ 对应的左矢为 $\langle\psi|=\begin{pmatrix}a^*&b^*\end{pmatrix}$。任意量子系统注意到我们目前讨论的都是 1/2 自旋系统,因此一对基由两个正交的矢组成,测量结果也仅有 $+{1\over2}\hbar$ 和 $-{1\over 2}\hbar$ 两种。这显然不足以描述许多量子力学系统,因此我们将其扩展:对应测量结果 $a_n$ 的量子态为 $|a_n\rangle$,而这些量子态都满足狄拉克记号章节中所述的全部量子力学基本公设,即正交性与完全性,具体数学表述为下:正交性:$\langle a_i|a_j\rangle = \delta_{ij}$,其中 $\delta_{ij}$ 为克罗内克δ函数,满足 $\delta_{ij} = \left\{\begin{matrix}1 & (i=j)\\0 &(i\ne j)\end{matrix}\right.$完备性:$\forall|\psi\rangle:|\psi\rangle=\sum_i\langle a_i|\psi\rangle|a_i\rangle$算符与测量在基本公设 (2) 中,我们提到了代表可观测量的算符。算符可以作用于右矢上,并产生一个新的右矢,即 $A|\psi\rangle = |\phi\rangle$。若右矢 $|\psi\rangle$ 和值 $a$ 满足 $A|\psi\rangle=a|\psi\rangle$,我们便称 $|\psi\rangle$ 为算符 $A$ 的本征态 (eigenstate),$a$ 为算符 $A$ 的特征值 (eigenvalue)。这引出了基本公设 (3),即对某个可观测量的测量结果只可能是与其算符 $A$ 的一个特征值 $a_n$。在 1/2 自旋系统中,对Z方向自旋的测量对应自旋算符 $S_z$,对此可以写出特征值等式$$S_z|+\rangle=+{\hbar\over 2}|+\rangle$$ $$S_z|-\rangle=-{\hbar\over 2}|-\rangle.$$由 $A=\begin{pmatrix}\langle+|A|+\rangle & \langle+|A|-\rangle\\ \langle-|A|+\rangle & \langle-|A|-\rangle\end{pmatrix}$ 可得 $S_z = {\hbar\over2}\begin{pmatrix}1&0\\0&-1\end{pmatrix}$。注意到 $S_z$ 为对角矩阵,且其对角项为为算符的特征值。这是因为该矩阵表示使用的基正是 $S_z$ 的特征向量。易证:使用其特征向量作为基表示的算符矩阵永远为对焦矩阵;在该表示下,特征向量即为单位向量。在已知其特征值等式的情况下,我们现在可以用矩阵表示某个算符。这一过程的逆向,即在已知算符之矩阵表示的情况下,预测测量其对应可观测量的可能结果,其实就是给定矩阵,求其特征值的问题,想必有线性代数知识的人都知道该怎么做:设 $\mathrm{det}|A-\lambda I|=0$,求解得到的 $\lambda$ 就是 $A$ 的特征值。厄米算符在使用矩阵表示的情况下,$A|\psi\rangle=|\phi\rangle$ 非常合理:矩阵乘矢量等于矢量。但对于左矢,算符必须处在左矢的右边才能产生有定义的结果;同时,注意到 $\langle\psi|A\ne\langle\phi|$。我们需要对算符也进行操作才能使这个等式相等。为此,引入厄米伴随算符 $A^\dagger$,满足 $\langle\psi|A^\dagger=\langle\phi|$。若算符 $A$ 与其自身的厄米伴随算符相等,我们则称之为厄米(埃尔米特)或自伴。自伴算符有两个重要性质:自伴算符必有实特征值;自伴算符的特征向量构成一套完备的基。投影算符$|\psi\rangle=(\langle+|\psi\rangle)|+\rangle+(\langle-|\psi\rangle)|-\rangle$ 中的 $(\langle+|\psi\rangle)|+\rangle$ 可以重写为:$$(\langle+|\psi\rangle)|+\rangle=|+\rangle(\langle+|\psi\rangle)=(|+\rangle\langle+|)|\psi\rangle$$注意到括号中的部分 $|+\rangle\langle+|$ 作用于 $|\psi\rangle$ 上并产生了一个新的右矢。显然,这是一个算符,我们称之为外积。外积具有完备性:$|+\rangle\langle+|+|-\rangle\langle-|=\Bbb{1}$ 当外积的左矢可由右矢进行厄米转置得到,它便是一个投影算符。对应某个本征态的投影算符作用于右矢 $|\psi\rangle$ 上会产生一个新右矢,其方向与该本征态相同,大小等于 $|\psi\rangle$ 处于该本征态的幅度(含相位)。测量我们已经在基本公设中提到过如何计算量子系统处于某一状态中的概率,但仅仅知道概率显然是不够的,为此我们将介绍均值和标准差的计算方法。量子系统的均值是其所有可能性的平均值,其数学描述为:$$\langle A\rangle=\langle\psi|A|\psi\rangle=\sum_n a_n \mathcal{P}_{a_n}$$其中 $a_n$ 为算符 $A$ 的特征值。量子系统的标准差则由对其均值的离差做平方再开二次方根得到,数学描述为:$$\Delta A=\sqrt{\langle(A-\langle A\rangle)^2\rangle}=\sqrt{\langle A^2\rangle-\langle A\rangle^2}$$对易算符量子力学中,有时两个变量可以同时精确测量(例如氢原子的汉密顿量和角动量),有时不行(例如粒子的位置和动量)。决定这一关系的便是对易算符 (commutator),亦称交换子。对于可观测量 $A,B$,其数学定义为 $[A,B]=AB-BA$。若该式等于零,则我们称 $A,B$ 是对易的。这意味着它们有相同的本征态,且我们可以同时知道它们的精确值。反之,如若两个正交方向的自旋算符 $S_x,S_y$ 的对易算符 $[S_x, S_y]=i\hbar S_y$ 不等于零,则我们无法同时知道它们的精确值;换句话说,我们无法在不改变对 $S_y$ 测量结果的情况下测量 $S_x$。不确定性原理在上一节中我们引入了对易算符,并介绍了它与测量的关系。在这一节中我们给出对易算符与可观测量的标准差之间的关系:$$\Delta A\Delta B\ge{1\over2}|\langle A, B\rangle|$$这就是量子力学不确定性原理,其最著名的例子便是粒子的动量和位置无法同时得知:$[x,p]\ge i\hbar$。

本博客现通过 $\KaTeX$ 支持 $\LaTeX$测试一下:薛定谔方程:$$ i\hbar\frac{d}{dt}|\Psi\rangle = \hat{H}|\Psi\rangle $$积分形式微分形式$$\text{积分形式: }\oint_A\vec{E}\cdot d\vec{a}=\frac{Q_{enc}}{\epsilon_0}$$$$\text{微分形式: }\nabla \cdot\vec{E}=\frac{\rho}{\epsilon_0}$$

注意:本指南为8.2.11版QQ写成。当在Play版QQ中打开黑夜和/或简洁模式时,总会提示设置失败。这是因为激活这些模式需要从腾讯的服务器下载额外的CSS资源,而此版本使用的资源地址已经不再受支持。要解决这个问题,就需要在QQ发送资源请求后,将其重定向到正确的地址。我们可以使用LightProxy或任何类似的应用来完成这一操作。在此以LightProxy为例,提供一个解决方法。从上述链接中下载LightProxy并安装在LightProxy的规则中加入:http://showv6.gtimg.cn https://showv6.gtimg.cn http://iv6.gtimg.cn https://iv6.gtimg.cn http://gxh.material.qq.com https://gxh.material.qq.com http://qzonestyle.gtimg.cn https://qzonestyle.gtimg.cnCTRL+S保存规则,在右边栏中点击手机代理确保手机和运行LightProxy的主机处在同一网络下,按LightProxy的提示设置手机的代理;此处以类原生安卓系统为例:互联网 → <当前连接的Wifi> → 右上角'编辑'图标 → 高级选项 → 代理(手动)注:通常情况下可以不安装提供的证书打开QQ并重试打开黑夜/简洁模式,成功后可以将代理设回无并关闭LightProxy如果仍然失败,则在主机上的浏览器中打开LightProxy提供的地址,并在LightProxy中打开日志并寻找Username及Password字样使用日志中找到的凭证登录管理页面,并在其中找到以192.168开头的地址,依此再次设置手机代理重试打开黑夜/简洁模式,成功后可以将代理设回无并关闭LightProxy

我在使用Krita的时候,发现系统内所有KDE应用(包括Krita, Konsole, Dolphin等)的菜单栏(如下图)都消失了。经过一番搜索之后发现这是一个从2018年就开始出现的bug特性。解决方法也并不难:打开终端,输入cd /home/%USERNAME%/.config,回车 (请把%USERNAME%替换成您的用户名)输入find ./ -type f -exec sed -i 's/MenuBar=Disabled/MenuBar=Enabled/g' {} \;,回车;打开系统设置,进入应用程序样式 > 窗口装饰 > 标题栏按钮, 移除"应用程序菜单";回到系统设置的第一级,进入开机与关机 > 后台服务 > 应用程序菜单守护程序,将其关闭;重启打开的KDE应用,现在菜单栏应该会出现了。没错,我又水了一篇文章 (ゝ∀・)

事情的起因要从我试图把Vim的默认字体设成Firacode说起。这套字体支持所谓"Ligatures",简单来讲就是可以把"->""!="等两个符号组成的常用操作符连成单个符号。然而我的Vim似乎并不支持这种魔法,研究一下之后发现是我的Vim版本过旧所致。然而Debian的祖宗之法使得bullseye版本的官方.deb包最高只到8.2.2434,并不支持这套字体;Vim官方提供的Appimage也没法正常运行,那就只好自行编译了。经过了一番折腾之后,总结出来的步骤如下:sudo apt-get install libncurses libgtk2.0-dev libatk1.0-dev libcairo2-dev libx11-dev libxpm-dev libxt-devsudo apt-get build-dep vim-gtk vim-x11 #安装依赖git clone https://github.com/vim/vim.git #从Github获取编译所需的源代码cd vim/src #移动到vim/src/路径下sudo apt-get install ruby-dev #(可选)安装ruby支持./configure --with-features=huge --enable-gui=gtk3 --with-x #设置编译参数,确保编译后的结果带有GVimmake #编译sudo make install #安装,完成安装完成之后,Vim依然不支持Ligatures,需要手动启用这一功能::set guiligatures=!\"#$%&()*+-./:<=>?@[]^_{\|~ #这一串字符为允许Ligatures起作用的字符教程结束!

如果你使用过一些开源软件(例如Krita, QGIS和FreeCAD),你会发现它们都是基于Qt框架的。尽管它们中的一部分允许你在偏好设置里直接更改应用的字体,但另一部分则由于一些原因而没有加入这种功能。很不幸的是,这些应用在中文Windows系统下的默认字体都是臭名昭著的SimSun,即仿宋体(如下)。不过,由于这些软件使用的都是Qt框架,修改它们的默认字体相当容易。首先,你需要找到这些软件的Qt Stylesheet文件。以FreeCAD为例,你可以在<应用安装目录>\data\Gui\Stylesheets下找到这些.qss后缀的文件。如果这个目录下有多个.qss文件,则说明你的应用程序支持切换颜色主题。你只需要随便选一个,之后再在应用内切换成这个主题文件即可。注意: 你最好在开始下一步前备份一下现在的.qss文件,以免你不小心搞砸了什么东西...接下来,打开这个文件。在它的开头,你可以找到这样的一段代码:* { padding: 0px; margin: 0px; border: 0px; border-style: none; border-image: none; outline: 0; color: #f5f5f5; /* Default color for labels and different text elements that usually use dark colors */ }这段代码规定了该主题下软件的默认样式,而要修改默认字体,你只需要再在color: #f5f5f5;后面添加一行font-family: "Source Sans Pro";。如果你的电脑上有这一字体的话,这行代码会将程序的默认字体设为思源黑体。当然,你也可以将它改成其它的字体,或是根据这个参考页面更改其它的默认参数。完成修改后,保存这个.qss文件。在软件内切换到你修改过的主题或是重启一下软件后,你的设置应该就会生效了。这是将FreeCAD默认字体改成思源黑体后的样子:至此,教程结束。

1. 什么是XMPP?XMPP,全称Extensible Messaging and Presence Protocol (可扩展消息与状态协议), 是一种以XML为基础的开放式即时通信协议。XMPP项目自1998年开始开发,于2000年5月正式发布。虽然你很可能从未听说过它,但实际上你大概率已经多次使用过它了: 许多游戏的内置聊天系统都是基于XMPP的, 天国的Google Talk也使用了这个通信协议。接下来,我将向你介绍XMPP的优势,以及如何使用它。2. XMPP的优势在哪?为什么要使用它?I. 可扩展正如我们之前所提到的一样,XMPP基于XML,也就是eXtensible Markup Language (可扩展标记语言)。这一特性使得XMPP的可扩展性非常强大, 可以支持大量的插件和附加功能。举个例子: 我希望每条消息不仅可以包含原本的文本内容,还可以包含一条发送者所在国家的信息。那么,我们就只需要给客户端加入一个插件,使它可以在发送时添加这条信息并在读取时解读它。比如说,Adam想发送一条内容为"Hello"的信息到Betty的账户上,那么:原来的客户端的信息:<message from="adam@example.com"/> <message to="betty@example.com"> <body>Hello</body> </message>解读的结果就是Adam发送了一条内容为"Hello"的信息给Betty。加入了插件之后,信息变成:<message from="adam@example.com"/> <message to="betty@example.com"> <body>Hello</body> </message> <location type="available" > <country>CA</country> </location> 解读的结果是Adam发送了一条内容为"Hello"的信息给Betty; 同时Adam的客户端支持这个插件,他的所在国家是加拿大。由此可以看出,XMPP可以很简单地进行扩展。这也意味着,这个协议拥有大量的扩展: 在线状态,已读反馈... 这些插件让这个简单的协议变得非常强大。II. 分布式XMPP通信网络的结构和电子邮箱很像: 不同的邮箱域名之间可以互相通信,比如说Gmail和Outlook邮箱之间可以互发消息; XMPP也是这样, 比如这里(sedirk.cn)上的XMPP账号也可以与xabber.org上的另一个账号互发消息。因为这种分布式结构的缘故,即使这个网络里的某一个服务器故障了,其它服务器之间的通信也不受影响, 而不会像那些有中央服务器的通信工具(比如QQ, LINE)一样, 整个网络都陷入瘫痪; 同时, 因为每一台服务器都能连接上这个网络, 用户也有大量的XMPP服务提供商可以选择,而不必被限制只能使用一个提供商的服务。这个特点也使得XMPP的另一个重要特性成为现实,那就是它的自由性。III. 自由与安全我们之前提到用户可以自由选择XMPP服务提供商, 这意味着只要用户对服务提供商的使用协议不满意,可以随时改用另一家提供商的服务; 不仅如此, 用户还可以自行搭建自己的服务器,从而完全将自己的权利掌握在手中。在商业软件(比如QQ, 微信, LINE)中, 用户则根本没有这种选择的权利: 服务提供商可以随时无理由关停或锁死用户的账号, 或是强行要求用户同意它们的使用条款; 而在XMPP中,则不会有这种情况出现,用户也就可以享有最大程度的自由。除此之外,XMPP的核心协议和几乎全部的插件都是开放源代码的。这意味着XMPP通讯协议是完全开放透明的, 用户可以自由开发自己的客户端和服务器端程序,而不必被现有的程序所限制。这一特点在各大XMPP客户端应用上都有着体现: 因为有一整个开发者社区进行优化,它们的体积都非常小,通常小于100MB, 在运行过程中也只会占用极少量的内存空间; 相比之下, QQ等专有软件则有着动辄500MB的体积, 运行时也会占用大量的内存空间。此外,在数据隐私方面,XMPP还拥有OpenPGP, OMEMO等端对端加密程序,因此用户也无须担心自己的聊天内容被服务提供商或第三方获得。3. 那么,我该怎么使用XMPP聊天呢?I. 注册账户首先,你需要一个XMPP账户。在之前的介绍中我也提到,你有许多XMPP服务提供商可以选择。不过, 既然你是在这个提供XMPP服务的网站上看到了这篇文章,为什么不直接在这里注册呢? 当然, 其它服务提供商的注册方式也都与这里十分相似, 你大可以放心去使用它们提供的服务。下图为本网站上的XMPP注册页面:注册步骤:在"Username"中填写你想设置的用户名。"Name"作为你的昵称使用,可以不填。在"Email"中填写你的邮箱地址。这个邮箱将作为你找回密码的渠道使用。可以不填,但如果忘记了密码只能找管理员重置。在"Password"中填写你想设置的密码。在"Confirm Password"中再次填写你想设置的密码,防止填错。点击"Create Account"即可完成创建XMPP账户。现在你就可以开始使用XMPP服务了!II. 客户端现在,你应该已经拥有了自己的XMPP账号。下一步,你需要选择一个客户端。在xmpp.org上有大量针对不同平台的客户端推荐, 你大可以自己选择你喜欢的那一个。我个人推荐在Windows, MacOS或GNU/Linux系统里使用Gajim, 在安卓系统里使用Conversations, 在ios中使用Siskin IM或Monal。在接下来的教程中,我也将以这两个客户端为例。当然,这个网站也提供一个网页版的客户端,登录方式也很简单,在此不做赘述了。

对于我这种折腾佬来说,索尼的无反既便宜性能也不错,是一个作后背的极佳选择。然而,那些便宜大碗的机型的控制都非常糟心。例如NEX-5,只有一个拨轮,拿来作为项目的核心实在是不太够用。好在索尼为这些相机都做了一个PC控制软件,可以从电脑上控制参数,从而让我能享受较好的控制。为了给之后的项目铺路,今天我就来试着解析一下这个控制协议。首先先用软件监控接着相机的USB口的流量,这里我用了HHD的USB Analyzer。接上相机,控制其它参数不变,调整一个参数,捕捉流量信息。从B门开始逐渐调高速度直到1/4000s。然后关闭监控,回放记录:人肉解析数据流其实非常简单可以看见每个分包的数据都基本相同,只有一个数字不同,那这就是控制快门速度的参数了:25表示B门,26表示30s,27表示25s,以此类推可以找到所有快门速度对应的控制数值。对于ISO和光圈等参数同理,也可以分析出来。第一步解析到此结束,对于协议一开始相机和电脑握手的步骤就在下一篇文章再继续研究吧( ゚∀゚)

我自从买了a6300和斯坦尼康之后就一直在一个循环中挣扎:拍视频->上斯坦尼康->把肩带拆下来拍照片->手持怕摔->把肩带再装回去每天重复至少三次...这也是没有办法的事情嘛,谁叫我买了这台机器同时做摄影和摄像用途呢...然后我发现了这样一个好东西:Peak Design的肩带快扣!这玩意是这样子的:看起来超棒的一个设计...只可惜对我来说太贵了,148RMB一对虽说这样子的东西也有天朝仿制品,但是看评价似乎质量堪忧的样子然后我在翻着购物网站的时候它给我推了一个用登山扣的电脑包肩带想了一下之后...我明白了!这两个东西不是一样子的嘛...遂去附近的百货市场买了一对登山扣,装上去拆下来试试...拆装都超快的,甚至比PD店里面演示的还快而且这玩意还是全金属的!虽然是超薄的一层铝最重要的是这玩意的价格仅仅是Peak Design那玩意的0.054倍(^^所以说PD的快扣为什么那么受欢迎呢...大概就是因为它优雅一点罢看来我得更仔细地想一想怎么把我自己整的设计也弄优雅点了

为了把之前挖的说要搭一台UMPC的大坑给填上,必须要有一个足够小的、能当鼠标用的装置,所以就弄出了这么个玩意...首先看看这个项目的原型,Toshiba Libretto系列和Thinkpad 750,都是使用的指点杆然而指点杆太贵了,一个要40多,而且PCB还很大,装不进键盘里,所以实际上和摇杆没什么区别了...那就弄摇杆好了...然后事实证明便宜确实没好货,摇杆转20°左右就满量程了,而且阻尼很大,用起来让人觉得喝了假酒那么要怎么让它用起来稍微好一点呢?因为阻尼大,转起来很难精确控制转动的角度 --> 那就降低光标的移动速度然而这样光标要走过很长的距离时就很痛苦 --> 弄个加速键这样虽然说妥协很大,用起来远远不如小红点顺手,但是...嘿!它能用!再把左键,右键,中键加上之后用一段时间还算顺手,那就这样了吧...既然用了Arduino来当鼠标了,那不加一块屏幕就太浪费了于是就弄了那块128*64,0.96'的OLED屏幕显示下温度,风扇转速和警告信息,看起来相当不错(最终效果见上图)(测试中...)然后是用这玩意解决一些在测试其它系统的时候发现的问题:本来是准备用一个简单的霍尔+MOSFET的独立电路来做到控制主屏幕在开合时的开关的,结果P沟道MOSFET忘买了...再去为了一个MOSFET付十块钱的运费实在是不值,也懒得拿三极管做非门了...那就干脆用Arduino解决算了这里没什么好讲的,就是给栅极10k的下拉电阻似乎太小了,直接上680k下拉解决键盘是买的现成的,拿到手发现虽然质量还行,但是有Z+Shift会和方向左键冲突...本来这不是什么大问题,但是对于东方玩家来说实在致命...于是就弄了个自锁开关,按下会一直按Z,问题解决!最后,还有50%的剩余ROM空间,那就加个非常中二的Boot Screen好了...最后的最后,放下写的稀烂的代码(BootScreen删掉了)#include <Mouse.h> #include <Keyboard.h> #include <U8glib.h> U8GLIB_SSD1306_128X64 u8g(4, 5, 6); const int xPin = A0; const int yPin = A1; const int caliButton = 9; const int caliIndi = 16; const int lButton = 12; const int rButton = 10; const int mainSW = 3; const int scrlSW = 11; const int accSW = 2; const int zButtonSW = 1; const int CPUTempSensor = A5; const int battTempSensor = A4; const int fanPin = 0; const int hallSensor = 7; const int screenMOSFET = 8; //Pin configuration int xCali; int yCali; //Create variables for calibration int xCalied; int yCalied; int xProcessed; int yProcessed; int CPUtemp; int battTemp; int fanSpeed; boolean mouseSwitch; //Declaring variables void setup() { Serial.begin(9600); Mouse.begin(); mouseSwitch = 0; pinMode(accSW, INPUT_PULLUP); u8g.setFont(u8g_font_7x13B); } void loop() { CPUtemp = ((analogRead(CPUTempSensor) - 240) / 11); battTemp = ((analogRead(battTempSensor) - 240) / 11);//Temperature monitoring fanSpeed = (CPUtemp * 6) - 240; if (fanSpeed > 0){ analogWrite(fanPin, fanSpeed); }else{ analogWrite(fanPin, 0); }//Fan control if (digitalRead(hallSensor) == HIGH){ digitalWrite(screenMOSFET, HIGH); }else{ digitalWrite(screenMOSFET, LOW); } int xRaw = analogRead(xPin) - 512; int yRaw = analogRead(yPin) - 512; if (digitalRead(caliButton) == HIGH){ xCali = 0 - xRaw; yCali = 0 - yRaw; digitalWrite(caliIndi, HIGH); }else{ digitalWrite(caliIndi, LOW); } xCalied = (xRaw + xCali)/4; yCalied = (yRaw + yCali)/4; if (digitalRead(accSW) == LOW){ xProcessed = ((10 * cos(0.01 * xCalied)) - 10 + xCalied) / 10; yProcessed = ((10 * cos(0.01 * yCalied)) - 10 + yCalied) / 10; }else{ xProcessed = ((10 * cos(0.01 * xCalied)) - 10 + xCalied) / 16; yProcessed = ((10 * cos(0.01 * yCalied)) - 10 + yCalied) / 16; } if (digitalRead(mainSW) ==HIGH){ mouseSwitch = 1; }else{ mouseSwitch = 0; } if (mouseSwitch ==1){ if (digitalRead(lButton) == HIGH){ Mouse.press(MOUSE_LEFT); }else{ Mouse.release(MOUSE_LEFT); } if (!(digitalRead(rButton) == HIGH && digitalRead(scrlSW) == HIGH)){ if (digitalRead(rButton) == HIGH){ Mouse.press(MOUSE_RIGHT); }else{ Mouse.release(MOUSE_RIGHT); } if (digitalRead(scrlSW) == HIGH){ Mouse.move(0, 0, xProcessed / 4); }else{ Mouse.move(yProcessed, -xProcessed); } Mouse.release(MOUSE_MIDDLE); }else{ Mouse.press(MOUSE_MIDDLE); Mouse.move(yProcessed, -xProcessed); } } if (digitalRead(zButtonSW) == HIGH){ Keyboard.press('z'); }else{ Keyboard.release('z'); } u8g.firstPage(); do{ u8g.setFont(u8g_font_7x13B); u8g.drawFrame(2, 2, 126, 62); u8g.drawStr(4, 13, "CPU Temp:"); u8g.setPrintPos(70, 12); u8g.print(CPUtemp); u8g.drawStr(4, 27, "Batt Temp:"); u8g.setPrintPos(77, 27); u8g.print(battTemp); u8g.drawStr(105, 62, "RPM"); u8g.drawLine(105, 50, 126, 50); u8g.drawLine(105, 6, 126, 6); if (fanSpeed > 0){ u8g.drawLine(108, (-(fanSpeed / 6) + 50), 123, (-(fanSpeed / 6) + 50)); } u8g.drawStr(22, 48, "[ ][ ][ ]"); if (battTemp > 50){ u8g.drawStr(29, 48, "!"); } if (digitalRead(caliButton) == HIGH){ u8g.drawStr(50, 48, "*"); } if (digitalRead(zButtonSW) == HIGH){ u8g.drawStr(73, 48, "Z"); } } while(u8g.nextPage()); }By Zephyr2552020/8/21