米米的博客

做了一点微小的工作

前言

辉光数码管是一种利用气体辉光放电显示数字的电子元件。玻璃管中包括一个金属丝网制成的阳极和多个阴极,阴极做成数字形状,加高压后管内气体发光,即可显示出数字。下图是苏联生产的 IN-14 辉光管,为节省成本,它显示的「2」和「5」用的是同样的模具,只是颠倒过来了。

图片来自:https://en.wikipedia.org/wiki/Nixie_tube#/media/File:ИH-14_(IN-14)_Nixie_Tubes_Displaying_"25".jpg

辉光管的缺点也很明显,它的使用寿命很有限,并且需要高压才能点亮,因而逐渐被淘汰。今天辉光管仍有小规模的生产,但辉光管的意义更多的是以复古风格体现出对早期科技文化的怀旧,而不是实用价值。在许多小说、游戏和影视作品中,辉光管都作为蒸汽朋克(Steampunk)风格的代表出现。动漫《命运石之门》中的「世界线变动率探测仪」便是这样一例。这在原剧中出现了多次,有网友将其复刻了出来:

在游戏《传送门 2》中,同样出现了类似辉光管的显示装置。不过它的尺寸比较大,已经接近霓虹灯了。霓虹灯的发光原理与辉光管类似,都是依靠气体放电。非常有趣的是,辉光管往往与蒸汽朋克联系在一起,而霓虹灯则是赛博朋克的必备元素。

利用辉光数码管和单片机,即可制作出蒸汽朋克感的智能家居。主控采用 Arduino 或者 ESP32,借助于它们强大的功能,可以简洁而优雅地控制辉光管显示时间、温度等数字信息。通过进一步地开发配套的手机应用,即可通过 Wi-Fi 和蓝牙方便地展示任何自定义内容。

阅读全文 »

在前面的文章自己打造一台恩尼格玛密码机中,介绍了使用 Arduino Mega 2560 实现一个简易 Enigma 机的方法。这个型号的 Arduino 单片机拥有 50 多个数字 IO,因此可以妥善地处置按键输入,并控制大量的发光二极管(键盘灯)及数码管。
但是,其它型号的 Arduino 就不一定能完成这个任务了 —— 例如 Arduino Leonardo 只有 20 个数字 IO。那么,有没有办法拓展这些输出接口呢?答案是肯定的。借助于移位寄存器,Arduino 可以将串行信号转为并行,以此通过较少的引脚来控制多路输出。

首先我们来看看一看移位寄存器的工作原理。这里涉及到数字电路中 D 触发器的特性。D 触发器在时钟的上升沿触发,触发后其输出 Q 锁定为此时数据输入引脚 D 的状态,直到下一次触发。

在下图所示的电路中,每一个时钟脉冲后,每个 D 触发器都会把输入的数据「送」到下一级的 D 触发器中。

阅读全文 »

Electron 是一个基于 Node.js,并拥有一个 Chromium「外壳」的桌面应用开发框架。你可以调用所有 Node.js 和浏览器的 API,使用 JavaScript,HTML 和 CSS 等 Web 技术创建原生程序。根据官方的宣传语:「它负责比较难搞的部分,你只需把精力放在你的应用的核心上即可。」
下面介绍如何使用 Electron 构建简单的桌面应用。你可以参照官方给出的入门程序:

1
git clone https://github.com/electron/electron-quick-start.git

安装

Electron 可以通过 npm install electron 来进行安装。在依赖包安装完成后,Electron 会开始下载它的「本体」—— 一个数十 MiB 大小的压缩包,包含 Electron 在不同平台下的可执行文件。这一步对于国内的开发者不太友好,因为下载的内容在 Amazon 云上,访问速度不佳;而且新版的 Electron 去除了下载进度条,导致即使出现问题,你也无法知晓卡在了哪一步。一种简单的解决方案是通过设定环境变量来使用淘宝源:

1
ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"

设置此环境变量后,再执行 npm install,下载就是正常的了。

阅读全文 »

通过 AIDA64 可以获得大量的传感器数据,例如 CPU 频率、温度,显存、内存使用情况等。并且,软件还可以将这些数据输出到兼容的 LCD 或 VFD 屏幕上。对于大部分 DIY 爱好者,这个功能已经足够强大了。不过,如果你试图通过高级语言编程来收集和处理数据,就会遇到困难 ——AIDA64 似乎并没有提供方便的接口。在设置项中苦苦搜寻了一番,笔者只找到了一个基于 HTTP 长连接的网络接口,配置起来还比较复杂。
为了避免重复造轮子,笔者转而前往 GitHub 搜索,发现了一个名为 aida64-to-json 的项目。它的原理非常简单:设置 AIDA64 将传感器数据写入注册表,然后读取注册表中的传感器参数并格式化。
Bingo!这正是一个完美的解决方案,之前居然没有想到。使用方法也很简单,需要进行一些设置:
文件 → 设置 → 外部程序 → 允许将监测数据写入注册表

AIDA64设置

然后就可以读取注册表信息了。aida64-to-json 是基于 Node.js 的,笔者又用 Python 重写了一遍:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import os, winreg

def query():
if os.name != "nt":
pass
db = {}
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\FinalWire\\AIDA64\\SensorValues") as key:
for i in range(winreg.QueryInfoKey(key)[1]):
name, data, _type = winreg.EnumValue(key, i)
attr = name.split(".")
if (attr[0] == "Label"):
db[attr[1]] = {}
db[attr[1]]["label"] = data
else:
db[attr[1]]["value"] = data
return db

if __name__ == "__main__":
db = query()
print(db)

此外还有一个可行的方案:利用 AIDA64 的共享内存特性,用 C++ 写一个 Node.js 或者 Python 的插件。其实 Rivatuner 也有共享内存可以用,可惜文档太少,不知从何下手。
笔者随后又到 AIDA64 的社区中搜寻,发现了诸如「如何将传感器数据通过串口输出 Arduino 上」这样的问题,但都没有得到可靠的回复。这样比较下来,读注册表似乎确凿是一个很省事的方案了。

ssh 连接远程服务器时,如果连接断开,那么当前的进程就会被杀死。运行系统备份或 ftp 传输这样耗时较长的任务,ssh 不方便一直挂着,那该怎么办呢?这种情况的应对方法是 GNU Screen,一款由 GNU 计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换。

在执行快速和简单的任务时,往往不会使用 screen,因为这没有必要。但是,如果发现正在运行的任务花费的时间比预期的要长得多,或者只是单纯地忘记了在执行命令前进入 screen,该怎么办呢?这时退出 ssh 就会导致前功尽弃。在这种情况下,我们剩下三个选择:

  • 一直保持 ssh 连接,但不知道要等到什么时候
  • 退出当前进程,丢失所有未保存的工作,并可能浪费大量的时间来处理,或者
  • 将正在运行的进程移至新的 screen 中。这是笔者将在后文中描述的解决方案。

操作步骤如下。

挂起进程

我们需要做的第一件事是通过按 Ctrl+Z 挂起当前的进程。
这会向进程发送一个 TSTP 信号 —— 停止执行进程,并且内核将不再为该进程安排更多的 CPU 时间。

在后台恢复进程

输入 bg 命令。这会将 SIGCONT 信号发送到该进程,现在它会在后台欢快地运行起来。

disown 进程

现在,我们像这样运行 disown 命令:

1
disown %1

disown 从活动作业表中删除该进程,从本质上允许该进程被另一个会话接管。

新开 screen

执行 screen 即可,进入一个新的 screen 会话中。

查找进程的 PID

现在,我们需要找到要接管的进程的 PID。笔者使用和推荐的方法是 pgrep。例如,如果我们的进程称为 myprogram,则可以运行 pgrep myprogram 命令,该命令将返回其 PID。

使用 reptyr 接管进程

最后,我们将 PID 传递给 reptyr 来接管该进程。如果 pgrep 给我们的 PID 为 1234,我们现在可以使用以下命令:

1
reptyr 1234

最后两步也可以合在一起:

1
reptyr $(pgrep myprogram)

如果提示找不到 reptyr 命令,可以用包管理工具安装一下。reptyr 的源码在这个 GitHub 仓库中。


本文翻译自:Move a running process to screen

0%