10
11
2018
19

获得高精度环形镜子一枚

如图:

高精度环形镜子

这面镜子上边有好几百G数据呢,然而早已读不出来了。

镜子来源于九年前的西数移动硬盘。因为太老了所以坏掉了吧,反正是识别不了了。最近看到 YouTube 上有人各种折腾硬盘,群里又有人拆了好几面镜子出来,所以我把它找出来拆啦。这镜子比我那总也擦不干净的丽塔芙镜子清晰多了呢,就是小了点儿。

拆起来也不难。首先想办法把壳弄开。然后见着螺丝就旋下来,见着贴纸就撕掉。那覆盖一个螺丝孔的小圆片不用撕下来,直接螺丝刀往中间捅,然后把螺丝旋下来就好了。

HDD 拆解中

覆盖磁头的那块金属有两个螺丝,其中一个在洞里。它上边有块形状奇怪的磁铁,照片里吸了很多螺丝的就是了。磁头是直接翻个面,让重力把它拉下来就可以了,我之前以为还有螺丝之类的还弄了好久呢,结果手一翻它自己掉下来了。马达中间那个螺丝很不容易取下,因为整体会跟着转。我是用剪刀卡住它的两个洞才给旋下来的。剩下的手拆就可以了。

HDD 拆解完毕

Category: 硬件 | Tags: 硬件 硬盘 拆解
2
12
2018
16

大上 Paperlike HD 电子墨水屏开箱体验

刚听说就已心动,无奈当时并不支持 Linux。后来由于一些事情耽搁到现在,终于到手了~

开箱啦

显示器整体尺寸是31cm×27cm,其中显示屏尺寸不到26cm×21cm(请注意:手工测量有误差)。分辨率是2200x1650。也就是200dpi多,和我的 Kindle Paperwhite 一代差不多的。

显示器下方是两个纸盒,里边是Y形线(照片中没有)、简易支架(那根根子)、螺丝和仅几百M的驱动U盘。

附件

Y形线是附加了USB电源线的HDMI线。信号走HDMI,电源走USB,所以需要额外占用一个USB口。当然接充电器上也是可以的,只是在电脑边接个充电器更不方便。

工作时,USB端口的电流为30~50mA左右,并不像说明书上说的需要2A那么多,挺省电的。对比之下,我的罗技鼠标接收器也需要15mA左右的电流呢。

线都接上之后,屏幕会闪几下,然后就可以用了。只是每隔几分钟会弹出提示信息,要求安装并运行所谓的「驱动」。下图是默认的 floyd 模式:

未使用软件,显示的登录界面

为了更多的模式,以及最重要的,别显示那个提示信息,需要安装并运行大上提供的软件。

软件是为 Ubuntu 提供的,但是 Arch 下也可以使用。下载并解包,将得到的三个文件「PaperLikeHD」、「ResChange」、「DS.ico」放到/usr/local/sbin/下,然后sudo PaperLikeHD 运行,会弹出一个包含一列按钮的窗口。不给 root 权限是不行的,会什么也不做就退出。

但是这样还不够。我使用的时候它总是报告找不到显示器。客服不肯告诉我它到底使用什么机制检测的,所以我 strace 又反汇编看了一下,最后发现它在找 /dev/i2c-* 设备文件,而我的系统上没有它们。看了一下一堆以 i2c 开头的内核模块,最后发现只要加载 i2c-dev 模块就好了。大上的软件需要一些时间来检测,等一会儿它就会在终端打开出「setting...50」这样的文字,这时就好了。

在台灯下使用火狐发推

过程中我还专门启动到 Ubuntu live 系统里测试来着。后来才知道原来是自己的手速太快,软件还没检测到,其实等等就好 (╯‵□′)╯︵┻━┻

Ubuntu live

从图片中可以看到,floyd 模式的显示很粗糙。这是因为它实际上只有二阶灰阶,通过不同密度的点来近似不同的灰度。虽然显示有很严重的颗粒感,但是它响应飞快,常规打字操作时几乎感觉不到延迟,很适合写作和阅读文本。而真正的二阶灰阶模式 A2,只有黑白两色,虽然依旧反应快速,但是因为非黑即白,只能用来读纯文本,任何阴影或者灰色的字都不好处理。

16灰阶的 A16 模式,显示清晰、层次丰富,但是响应速度非常慢。也不是非常啦,除了屏幕大小外,无论显示效果还是响应速度都跟我的 Kindle 一样的。而与 Kindle 不同的是,它会在更新时将更新区域变黑再显示,造成闪烁。在此模式下使用鼠标非常非常费力,任何非静止的元素(比如火狐载入中的动画、时钟、光标移动)都挺分散注意力的。

以上都是所谓的「可变分辨率模式」。另外有个「固定1100x825模式」,也就是使用一半的分辨率。至于另一半去了哪里,看看它所支持的模式就能猜到了:

  • A5,也就是五灰阶。这是用四个墨滴来显示一个像素,每个墨滴只有黑与白两种状态。
  • A61,所谓的61灰阶。也是用四个墨滴来显示一个像素。不过每个墨滴竭尽所能有16种状态,也不知道大上是怎么组合出这61灰阶的。

也不知道大上为什么把这两种墨滴用法叫作「可变分辨率模式」和「固定1100x825模式」。哪里可变了,又哪里固定了呢?这两种模式切换时,会调用「ResChange」程序,它会影响当前的显示器布局,需要重新使用 xrandr 进行设置。

以下是各种模式显示这个灰阶测试网页的照片:

A2 模式:

A2 模式

A16 模式:

A16 模式

floyd 模式:

floyd 模式

A5 模式:

A5 模式

A61 模式:

A61 模式

半分辨率下,清晰度做出了很大的牺牲。以下是 A16 和 A61 模式显示 PaperLikeHD 软件自身界面的效果对比:

A16 A61

在 A2、A5、floyd 模式下,可以调节对比度,也就是墨滴到底显示为黑还是为白的值,以在显示不同的页面时都能将文本与背景良好区分开。

和 Kindle Paperwhite 不同的是,它没有背光。在晚上的时候,屏幕偏暗,附加一个台灯光源比较好。不过它的屏幕也不像 Kindle 那样偏黄。

这篇文章最终定稿,就是在 PaperLikeHD 上完成的,使用的是 floyd 模式。我个人觉得半分辨率的几个模式很鸡肋。目前觉得,写作用 floyd 模式,文本阅读使用 A2 模式,网页阅读使用 A16 模式,这样最好了~

floyd 模式还有个问题:在显示某些图片时(比如我的 Awesome 桌面壁纸),那些墨滴颗粒会不断地抖动,就像风在吹沙粒一样……

最后,这里是大上的官网链接

Category: 硬件 | Tags: linux 硬件 E-ink 显示器
12
10
2017
11

在 Linux 下设置录音笔的时间

咱买了一个录音笔,效果比使用笔记本话筒录音好多了还省电。当然啦,我也曾试过使用手机录音,结果是,没能录多久就中断了(Android 就是这么不靠谱)。

我的录音需要记录较为准确的时间信息。录音笔怎么知道现在是什么时间呢?还好它没有跟风,用不着联网!

它带了一个小程序,叫「录音笔专用时间同步工具」(英文叫「SetUDiskTime」,可以搜到的)。是一个 EXE 文件,以及一个 DLL 文件。功能很棒,没有广告,没有推荐,也不需要注册什么乱七八糟的账户,甚至都不需要打开浏览器访问人家官网。就弹一个框,显示当前时间,确定一下就设置好时间了。这年头,这么单纯的 Windows 软件还真是难得呢。

然而,它不支持我用的 Linux 啊。虽然我努力地保证这录音笔一直有电,但是时间还是丢失了几次,它的FAT文件系统也脏了几次。每次我都得开 WinXP 虚拟机来设置时间,好麻烦。

Wine 是不行的,硬件相关的东西基本上没戏。拿 Procmon 跟踪了一下,也没什么复杂的操作,主要部分就几个 DeviceIoControl 调用,但是看不到调用参数。试了试 IDA,基本看不懂……不过倒是能知道,它通过 IOCTL_SCSI_PASSTHROUGH 直接给设备发送了 SCSI 命令。

既然跟踪不到,试试抓 USB 的包好了。本来想用 Wireshark 的,但是 WinXP 版的 Wireshark 看来不支持。又尝试了设备分配给 VBox 然后在 Linux 上抓包,结果 permission denied……我是 root 啊都被 deny 了……

那么,还是在 Windows 上抓包吧。有一个软件叫 USBPcap,下载安装最新版,结果遇到 bug。那试试旧版本吧。官网没给出旧版本的下载地址,不过看到下载链接带上了版本号,这就好办了。去 commit log 里找到旧的版本号替换进去,https://dl.bintray.com/desowin/USBPcap/USBPcapSetup-1.0.0.7.exe,就好了~

抓好包,取到 Linux 下扔给 Wireshark 解读。挺小的呢,不到50个包,大部分还都是重复的。很快就定位到关键位置了:

关键 SCSI 命令

一个 0xcc 命令发过去,设备回复「ACTIONSUSBD」,大概是让设备做好准备。然后一个 0xb0 命令,带上7字节数据发过去,时间就设置好了。简单明了,不像那些小米空气净化器之类的所谓「物联网」,通讯加密起来不让人好好使用。

那么,这7字节是怎么传递时间数据的呢?我首先检查了UNIX时间戳,对不上。后来发送这个字串看上去挺像YYYYMMDDHHMMSS格式的,只是明显不是当时的时间。啊,它是十六进制的嘛!心算了几个,符合!再拿出我的 Python 牌计算器,确定年份是小端序的16位整数。

好了,协议细节都弄清楚了,接下来是实现。我原以为我得写个 C 程序,调几个 ioctl 的,后来网友说有个 sg3_utils 包。甚好,直接拿来用 Python 调,省得研究那几个 ioctl 要怎么写。

#!/usr/bin/env python3

import os
import sys
import struct
import subprocess
import datetime

def set_time(dev):
  cmd = ['sg_raw', '-s', '7', dev, 'b0', '00', '00', '00', '00', '00',
         '00', '07', '00', '00', '00', '00']
  p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
  dt = datetime.datetime.now()
  data = struct.pack('<HBBBBB', dt.year, dt.month, dt.day,
                     dt.hour, dt.minute, dt.second)
  _, stderr = p.communicate(data)
  ret = p.wait()
  if ret != 0:
    raise subprocess.CalledProcessError(ret, cmd, stderr=stderr)

def actionsusbd(dev):
  cmd = ['sg_raw', '-r', '11', dev, 'cc', '00', '00', '00', '00', '00',
         '00', '0b', '00', '00', '00', '00']
  subprocess.run(cmd, check=True, stderr=subprocess.PIPE)

def main():
  if len(sys.argv) != 2:
    sys.exit('usage: setudisktime DEV')

  dev = sys.argv[1]
  if not os.access(dev, os.R_OK | os.W_OK):
    sys.exit(f'insufficient permission for {dev}')

  actionsusbd(dev)
  set_time(dev)

if __name__ == '__main__':
  main()
Category: Linux | Tags: Linux USB 硬件 SCSI

部分静态文件存储由又拍云存储提供。 | Theme: Aeros 2.0 by TheBuckmaker.com