Old AOC 15″ LM565 LCD repair

I’m not even sure this warrants a blog post. The only thing that was wrong with it was a loose ribbon cable connecting one of the two analog boards to the logic board.

Symptoms: LED and backlights power on, but no logo, no menu. If you connect a VGA cable, the monitor is identified correctly and can be enabled, but no picture.

So… just in case anyone needs board pictures, here they are:

Buttons and sound output
Boards, front side
Boards, back side, and LCD panel

Yay, 1024×768. It was an upgrade from 800×600 back when I got it…

Christmas illumination using breadboards

Just a thing I quickly made a short while ago. There’s nothing special going on. The board on the left has one resistor per LED, on the board on the right, two LEDs and one resistor are each wired as a series circuit.

Note: I don’t leave this running unattended — I’m reasonably sure the entire thing would fall to the floor in a medium~major earthquake and the risk of causing a short is relatively high. Not that the short would necessarily cause a fire, but better safe than sorry.

Merry Christmas

Arduino “warning: internal error: out of range error”

There are probably a million other reasons you could get this error, but I didn’t see anyone document the case I got it: I wrote some raw assembly (i.e., hexadecimal machine code) and got the instruction length wrong. I.e., something like this:

__asm volatile(
    ".byte 0x00 \n"

Well, AVR instructions are 16 bits, so clearly the one-byte thing above wouldn’t encode a valid instruction and would ruin alignment, so it would have to look at this:

__asm volatile(
    ".byte 0x00 \n"
    ".byte 0x00 \n"



アマゾンやその他ショッピングサイトやユーチューブなどでレビューを色々読んで、AINX (アイネクス) の AX-S3W にしました。(Amazon: https://www.amazon.co.jp/dp/B07ZNDHJ7Y / 実際に購入した楽天のサイト (ちょっとだけ安かったので: https://item.rakuten.co.jp/a-price/4582519730020/)

  • siroca 2WAY の食洗機にしなかった理由は、皆さんのレビューでは乾燥機能はあまり評価がよくなかったから。オートオープンは良さそうですが、少しだけ乾燥してからオートオープンとかは出来なそうでした。UV も良さそうですが、まぁ本当に要る?と自分に問いかけたら、そこまで要らないかな、と思いました。
  • アイリスオーヤマも乾燥機能は低評価でした。
  • Aqua も乾燥機能はやや低評価でした。
  • 東芝も乾燥機能は低評価でした。
  • パナソニックはタンク式ではないので無理でした。
  • Thanko にしなかったのも乾燥機能の低評価でした。また、給水ホースが繋げません。現在は手動で水を入れており今の住まいでは給水ホースの出番はなさそうですが、いつか引っ越したらまた変わるかもしれないので、自分の頭の中ではマイナスでした。
  • Maxzen, iimono117, moosoo は皆同じだと思います。もしかしたら、Maxzen は乾燥機能が温風ではなくただの送風かもしれない?また、少なくともアマゾンでは moosoo は現在品切れ中のようです。moosoo にすべきか、かなり迷いました。乾燥機能は一番しっかりしていて、洗浄温度も高くて洗い残しの心配はなさそうです。ただし、moosoo にしなかったのは、すすぎの温度も乾燥の温度も高くて、プラスチック製の容器は心配だったから。お急ぎモードではやや低かったような気がしますが、時間が短いです。また、「野菜洗い」というコースが良さそうですが、実はAINXの「水洗い」コースは海外のサイトで「野菜洗い」用と書かれていたので、AINXも野菜洗いができるかと思います。(ただし、野菜洗いは試したことがありません。ちょっと汚れのひどいほうれん草とかじゃがいもなら良いかも?)また、乾燥のみのコースがないそうです。
  • Kwasyo は機能が良さそうだけれども、日本市場への参入はかなり最近なのでサポート体制など、少し心配でした。ただし、海外のアマゾンでは複数のモデルが売られているようなのでそこまで心配は要らないかもしれません?→ https://www.amazon.com/Kwasyo-Portable-Countertop-Dishwasher-High-temperature/dp/B08V5PNMW5

AINX は、乾燥機能は最初の10分間は温風になるので、送風だけよりはマシかと思いました。
また、moosoo より形が格好良く、光はきれいだと思いました。(すぐに消えますが)
また、海外のアマゾンでも (“Novete” という名前になりますが) 売られています: https://www.amazon.com/dp/B089YD3Z91/
海外のアマゾンのレビューも良かったですし、ユーチューブにも海外のユーチューバーさんが良いレビューを残しています: https://www.youtube.com/watch?v=9F1c1pxvicw
続いて、洗浄力です。普通の食洗機は二回洗い式です。一回目(「プレウォッシュ)は少量の洗剤と少量の水で大きなゴミを落として、水を排水してから、「メインウォッシュ」を行います。そのため、普通の食洗機には洗剤を入れるところが2つ付いていることが多いです。ただし、少なくとも AINX には一つしか付いていません。プレウォッシュはなくて、最初から本番です。
汚れが落ちないわけではありませんが、たまに、油こい料理の場合、特に上カゴ(カトラリー入れ)や下かごのプラスチック製容器が少しだけベタベタすることがありましたが、Finish のタブレットをやめてキュキュットのクリア除菌(オレンジオイル配合)の粉系の洗剤に変えたら(量や汚れ具合によって多めに入れて、)そういうことは全くなくなりました。
Finish でも、ストロングにするのもある程度効果的だったと思います。キュキュットではストロングを使うことはありません。
AINX は今年(2021年)UV 搭載のモデルをリリースするようなので、ブリーズモードの併用ができたら更に衛生的になりそうです。

ところで、オフハウスで「ちょうどいい」と思って2500円で買ったスタンディングデスクに食洗機を乗せて使っています。振動とかは特にないです。(https://direct.sanwa.co.jp/ItemPage/100-DESKF009 これによく似たものです)

Outputting QR codes on the terminal

In these dark ages, a lot of software (mostly chat apps) only work on smartphones. While it’s easy to connect a USB-OTG hub to most smartphones (even my dirt-cheap Android smartphone supports this (now three years old)), having two keyboards on your desk can be kind of annoying.

While there are a bunch of possible solutions to this problem, many of these solutions do not fix the problem when you’re not on your home setup. Which is why I often just use QR codes to send URLs to my phone, and there are a lot of QR code generator sites out there.

QR code generator sites are useful because they work everywhere, but many are slow and clunky. Perhaps acceptable in a pinch, but… what if you could just generate QR codes on the terminal?

Well, some cursory googling revealed this library: https://github.com/qpliu/qrencode-go, which doesn’t have any external (non-standard library) dependencies, is short enough to skim over for malicious code, and comes with an easily adapted example. (I am reasonably confident that there is no malicious code at ad8353b4581fa11fc01a50ebf56db3833462fc13.)

Note: I very rarely use Go. Here is what I did to compile this:

$ git clone https://github.com/qpliu/qrencode-go
$ mkdir src
$ mv qrencode/ src/

$ cat > qrcodegenerator.go
package main
import (
func main() {
var buf bytes.Buffer
for i, arg := range os.Args {
if i > 1 {
if err := buf.WriteByte(' '); err != nil {
if i > 0 {
if _, err := buf.WriteString(arg); err != nil {
grid, err := qrencode.Encode(buf.String(), qrencode.ECLevelQ)
if err != nil {
$ GOPATH=$PWD go build qrcodegenerator.go
$ ./qrcodegenerator test

Note: the above code is adapted from example code in the README.md file and is therefore LGPL3.

Since Go binaries are static (that’s what I’ve heard at least), you can then move the executable anywhere you like (e.g. ~/bin) and generate QR codes anywhere. Note that they’re pretty huge, i.e. for ‘https://blog.qiqitori.com’ (26 bytes) the QR code’s width will be 62 characters. For e.g. ‘https://blog.qiqitori.com/2020/10/outputting-qr-codes-on-the-terminal/’ (this post) the width is 86 characters.

Standing on the shoulder of giants

Making new discoveries usually requires knowledge from previous discoveries. Discoveries are published as text in research papers. Scientists find these research papers using keywords they plug into a search engine or when other research papers cite them. Being able to search by keywords has obviously made scientific research much easier than before.

However, the research papers themselves are still written in natural languages, and unless the authors avoid using grammatical features like the words “it” or “them” to avoid repeating nouns over and over again, it’s difficult to extract meaning from them.

So perhaps people shouldn’t be writing research papers in (e.g.) English and instead use something that is easier for computers to parse. The research paper would contain claims, some numeric indicator for how certain these claims are (or from where they came), how these claims came about (e.g. experiment (with instructions for how and experiment was set up and why), logical reasoning (with the actual chain of reasoning), etc.). Then you could, for example, search for claims, instead of just keywords.

Instead of just using the keywords “ocean plastic waste”, you could search for “plastic waste in oceans negatively impacts ocean fauna”. Instead of typing in this query, you would choose every noun, verb and other qualifiers from a searchable menu. You would be able to display this menu in any language. The words in the menu would all mean a specific thing, and anybody would be able to look at the definitions and properties of every word. Eventually, the system could be programmed to (e.g.) look at two different claims and judge whether these claims might be related, based on common subjects or objects, and generate potential new claims all by itself. For example, claim 1: “Thunderstorms may under certain circumstances cause blackouts” and claim 2: “Certain atmospheric conditions cause thunderstorms” would logically mean that “certain atmospheric conditions cause blackouts”, which is true. The system probably shouldn’t let users use the word “certain” though.

How hard would it be to make such a system? Well, it’s best to start in a single niche and slowly expand the system. Here’s a very simple (completely static) example that is a bit different in that it just generates natural English or Japanese text based on what values are selected in the menus: https://blog.qiqitori.com/cve_generator/

Saving the selections would be a first step in the right direction. Currently, only one “allows attackers to:” is allowed, but you would probably want to 1) allow an arbitrary-length chain 2) something indicating the author’s degree of certainty (“may allow”), 3) add other verbs, other nouns, and 4) the reasoning behind a set of these claims (it gets complex here, but in the end you just have to select subjects, verbs, and objects, ifs, etc.).

Perhaps selecting things from a menu would get old quick (unless you just do it for the main claims). So the computer could try its best to analyze a sentence and ask the user to confirm that its interpretation is correct. The preceding sentence could be analyzed like this, but you’ll see that this could be tricky and just selecting something from a menu might be the better option after all: So [potential solution for previous follows:] the computer [the software] could try its best [could potentially (but probably wouldn’t manage to do this perfectly)] to analyze a sentence [analyze a given input sentence] and [afterwards] ask the user to [force the user] confirm that its [the software’s] interpretation [of the given input sentence] is correct [confirm … or force the user to edit the interpretation using a menu]. As you can see, there is a lot of context involved, which makes it hard to derive (e.g.) claims from natural text.

As you can see in the CVE generator, having the facts makes it somewhat easy for the system to generate text in any language for humans to read and think about

KDE: Windows freeze or flicker but application doesn’t crash

I’m running KDE on two different systems, and one of them exhibits the following problem very often, and the other just did for the first time:

Windows stop updating their content, and perhaps flicker a bit. Switching to a different window and back causes the window contents to be updated, but still frozen. Which means that the application itself is not crashed.

The following command fixes this:

kwin --replace

You can run this from the run command prompt (Alt+F2) (also called Plasma search or krunner), or you could run it in a terminal. (You’d have to make sure the process doesn’t exit when you close the terminal though.)

If everything appears to be frozen and you can’t get to the run command prompt, you could still switch to a console, log in, and try running the following:

DISPLAY=:0 kwin --replace

Both systems have internal Intel graphics (quite different chipsets though) and KDE5.

The above commands will fix the problem for that time. Your open applications should not be affected by the change. I haven’t looked much into permanent fixes, but changing the rendering backend (System Settings → Display and Monitor → Compositor) may change the frequency the problem is triggered or maybe even get rid of it altogether. (I felt that OpenGL 2.0 probably triggered the problem fewer times than OpenGL 3.1.)

I’ve noticed a fair amount of traffic to my KDE-related posts. If you run into any weird KDE problems that you don’t know how to fix, feel free to leave a comment and ask.

Meltdown / Spectre Kernel Patch Benchmarks on Older Systems

The Meltdown patch for the Linux kernel makes use of the relatively new PCID instruction. I still sometimes use my old laptop, which contains a Core 2 Duo Penryn CPU (T7250), and does not support the PCID instruction, so I did a quick UnixBench run to see what kind of difference the absence of the PCID instruction would make. At the end of this article, I have a bonus “benchmark” for an alternative way to mitigate Meltdown: disabling the CPU’s caches. All my tests were performed on Debian Wheezy (currently oldstable) using kernel version 3.16.0-5-amd64.

First of all, here are another person’s results for a CPU that supports PCID. And since that’s in Japanese, here’s the important bit:

Test Before After Change (positive is better)
System Call Overhead 5391.9 4009.7 -25.63%

Now, my tests on the Penryn CPU:

Test Before After Change (positive is better)
Dhrystone 2 using register variables 3360.4 3414.1 +1.60%
Double-Precision Whetstone 724.1 724 -0.01%
Execl Throughput 1351.7 1222.9 -9.53%
File Copy 1024 bufsize 2000 maxblocks 1582 1244 -21.37%
File Copy 256 bufsize 500 maxblocks 1255.9 922.1 -26.58%
File Copy 4096 bufsize 8000 maxblocks 1982.4 1810.6 -8.67%
Pipe Throughput 1672.8 765.4 -54.24%
Pipe-based Context Switching 1108.3 671 -39.46%
Process Creation 1150 1025.3 -10.84%
Shell Scripts (1 concurrent) 1995.7 1909 -4.34%
Shell Scripts (8 concurrent) 1831.8 1743.3 -4.83%
System Call Overhead 1705.6 544.9 -68.05%
System Benchmarks Index Score 1535.8 1160.9 -24.41%

And the raw data in case you are interested:

Before updating:

Test Score Unit Time Iters. Baseline Index
Dhrystone 2 using register variables 39215974.0 lps 10.0 s 7 116700.0 3360.4
Double-Precision Whetstone 3982.6 MWIPS 9.9 s 7 55.0 724.1
Execl Throughput 5812.4 lps 29.2 s 2 43.0 1351.7
File Copy 1024 bufsize 2000 maxblocks 626453.0 KBps 30.0 s 2 3960.0 1582.0
File Copy 256 bufsize 500 maxblocks 207854.8 KBps 30.0 s 2 1655.0 1255.9
File Copy 4096 bufsize 8000 maxblocks 1149781.6 KBps 30.0 s 2 5800.0 1982.4
Pipe Throughput 2080979.1 lps 10.0 s 7 12440.0 1672.8
Pipe-based Context Switching 443337.7 lps 10.0 s 7 4000.0 1108.3
Process Creation 14490.3 lps 30.0 s 2 126.0 1150.0
Shell Scripts (1 concurrent) 8461.7 lpm 60.0 s 2 42.4 1995.7
Shell Scripts (8 concurrent) 1099.1 lpm 60.1 s 2 6.0 1831.8
System Call Overhead 2558469.9 lps 10.0 s 7 15000.0 1705.6
System Benchmarks Index Score: 1535.8

After updating:

Test Score Unit Time Iters. Baseline Index
Dhrystone 2 using register variables 39842314.8 lps 10.0 s 7 116700.0 3414.1
Double-Precision Whetstone 3982.0 MWIPS 9.8 s 7 55.0 724.0
Execl Throughput 5258.5 lps 30.0 s 2 43.0 1222.9
File Copy 1024 bufsize 2000 maxblocks 492638.1 KBps 30.0 s 2 3960.0 1244.0
File Copy 256 bufsize 500 maxblocks 152610.9 KBps 30.0 s 2 1655.0 922.1
File Copy 4096 bufsize 8000 maxblocks 1050156.7 KBps 30.0 s 2 5800.0 1810.6
Pipe Throughput 952188.4 lps 10.0 s 7 12440.0 765.4
Pipe-based Context Switching 268401.0 lps 10.0 s 7 4000.0 671.0
Process Creation 12918.3 lps 30.0 s 2 126.0 1025.3
Shell Scripts (1 concurrent) 8094.2 lpm 60.0 s 2 42.4 1909.0
Shell Scripts (8 concurrent) 1046.0 lpm 60.1 s 2 6.0 1743.3
System Call Overhead 817288.1 lps 10.0 s 7 15000.0 544.9
System Benchmarks Index Score: 1160.9

Now, Mitigating Meltdown by switching off CPU caches:

You wouldn’t even want to run UnixBench without CPU caches. Here’s a “simpler” benchmark that tells you why:

# time perl -e 'for (1..1000000) {}'

real 0m0.056s
user 0m0.052s
sys 0m0.000s
# insmod disable_cache.ko
# time perl -e 'for (1..1000000) {}' 

real 0m44.689s
user 0m40.044s
sys 0m0.520s
# rmmod disable_cache

Unless you enjoy working on a system that is some 800 times slower. (Don’t try to do this in a GUI setting.)

Nonetheless, here’s some code to disable the CPU caches. (Modified from https://www.linuxquestions.org/questions/linux-kernel-70/disabling-cpu-caches-936077/)

#include <linux/init.h>
#include <linux/module.h>
#include <linux/smp.h>


void _disable_cache(void *p) {
 printk(KERN_ALERT "Disabling L1 and L2 caches on processor %d.\n", smp_processor_id());
 __asm__(".intel_syntax noprefix\n\t"
 "mov rax,cr0\n\t"
 "or rax,(1 << 30)\n\t"
 "mov cr0,rax\n\t"
 ".att_syntax noprefix\n\t"
 : : : "rax" );
void _enable_cache(void *p) {
 printk(KERN_ALERT "Enabling L1 and L2 caches on processor %d.\n", smp_processor_id());
 __asm__(".intel_syntax noprefix\n\t"
 "mov rax,cr0\n\t"
 "and rax,~(1 << 30)\n\t"
 "mov cr0,rax\n\t"
 ".att_syntax noprefix\n\t"
 : : : "rax" );

static int disable_cache_init(void)
 on_each_cpu(_disable_cache, NULL, 1);
 return 0;
static void disable_cache_exit(void)
 on_each_cpu(_enable_cache, NULL, 1);



obj-m += disable_cache.o

	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

Note that you need to indent using tabs in Makefile. CR0 can only be read from Ring 0, and thus a kernel module is needed.

Here’s some example code to just read the CR0 registers on all CPUs:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/smp.h>


void cache_status(void *p) {
 long int cr0_30 = 0;
 __asm__(".intel_syntax noprefix\n\t"
 "mov %0, cr0\n\t"
 "and %0, (1 << 30)\n\t"
 "shr %0, 30\n\t"
 ".att_syntax noprefix\n\t"
 : "=r" (cr0_30));
 printk(KERN_INFO "Processor %d: %ld\n", smp_processor_id(), cr0_30&(1<<30)>>30);

static int cache_status_init(void) {
 on_each_cpu(cache_status, NULL, 1);
 return 0;
static void cache_status_exit(void) {
 on_each_cpu(cache_status, NULL, 1);


And the corresponding Makefile:

obj-m += cache_status.o

	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules


KDE: The Window Switcher installation is broken, resources are missing.

So I was highly displeased with the standard Breeze task switcher, and thought I’d get a few new ones by clicking the star icon next to the drop-down menu where you select the task switcher. My recommendation is “Grid”. Trying to use Grid, all I get is this error message:

The Window Switcher installation is broken, resources are missing.
Contact your distribution about this.

Hrm. So then I Google and look at code, waste time trying silly things, just to postpone this problem for another weekend. Well, it’s the next weekend now, and just when I’m about to dive back into the code… I restart X (i.e. re-login), and when I try to bring the message up one more time… It doesn’t appear anymore, and Grid and all the others are working! I try installing one more, and sure enough, it didn’t work, but one more re-login and tada. So the answer to this problem might be: restart your KDE session.

It’s still a bug though. But unfortunately I’m no longer interested in looking into this bug now. :(