お化け探知機「化けたん」の再発明を目指して！

海外でお化け探しといえばEMF (電磁場、electromagnetic fields、実際には静電気や磁気) を使って検知するのがメジャーなようですが、化けたんは全く違う原理でお化けを探しているようです。化けたんの動作原理を理解し、自分でも同じようなお化け探知機を作りたいと思い、記事を書くことにしました。まだ「化けたん」の再発明には至っていませんが、最終的には回路図やプログラムを公開して、オープンソースなお化け探知機ができたらいいと思っています。
**化けたんオマージュの最小構成が完成しました！**

# 「化けたん（ばけたん）」とは？
[NMR ねとらぼミステリー調査班](https://nlab.itmedia.co.jp/nl/articles/2005/18/news106.html)や[日本ダウザー協会](https://www.j-dowsing.com/goods/baketan/)で詳しく書かれていますが、[ソリッドアライアンス](https://www.solid-a.com)という会社で開発されたガジェットで、空間の状態を乱数の偏りをもって判定する「おばけ探知機」だそうです(https://www.solid-a.com/baketan-kai-q/ )。
2005年に最初のバージョンが発売されていたのですが、私が購入したいと最初に思った数年前にはプレミア付きの高価なものしか手に入らない状態でした。
久しぶりに化けたんのことを思い出してアマゾンで検索してみると、普通の値段で購入できるようになっていたので早速買ってしまいました。https://amzn.to/3OVbVMn

# 化けたんの見た目と動作
## 見た目
本体は半透明プラスチック覆われていてで石ころをかたどったような形をしています。上面には目立たない形のボタンが一つだけ配置されていて、半透明なケースを通してマルチカラーLEDと小さな水晶が入っているのが見えます。[上のリンク](https://amzn.to/3OVbVMn)では写っていませんが本体底面には音を鳴らすためらしい直径1cm程度の圧電スピーカーが付いていて、実際にお化けを探知すると音が鳴るようです。
ねじを外して中を見てみると、圧電スピーカーはボタン電池ホルダのプラス側の金属に両面テープを使って止められており、さらに底面の蓋が4か所で支えています。います。プロセッサはSC92F7352という8052コア・マイクロコントローラ互換品のようです。ほかには表面実装用の抵抗、コンデンサ、トランジスタなどが並んでいます。よく見るとプロセッサの端子の一つからアンテナのようなパターンが見えます。裏面を見ると同じ場所にアンテナのようなパターンが見えます。二つのアンテナで電磁的な結合を狙っているようです。ほかには上記の圧電スピーカーがセンサーに使えそうです。
![IMG_20220720_おもて.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199416/ada8f1e2-a290-6d68-a94f-462cb8ff9d64.png)
![IMG_20220720_うら.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199416/cfc0f190-6e99-ba2f-871d-c7ea722c79ff.png)



## 動作
中央のボタンを押すとサーチモードに入りLEDの色が緑、黄色、赤、紫、青、水色、白、消灯など8色のうちからランダムに変化します。8回色が変わった後、探査結果が青、水色、緑、黄色、赤などに光って表示されます。色が変化するタイミングもランダムなようです。

# 本家の動作原理について
## ハードウエア
[NMR ねとらぼミステリー調査班](https://nlab.itmedia.co.jp/nl/articles/2005/18/news106.html)によると、化けたんには疑似乱数発生プログラムが実装されていて、「霊界アンテナ」と呼ばれている基盤のアンテナで **電磁波** や **静電気** 、 **音圧変化** などを受信し、これらのデータをもとに疑似乱数を発生させているそうです。さらに、 **アンテナは4つ** 搭載されていると書かれています。

## ソフトウエア
### お化け探知について
[日本ダウザー協会](https://www.j-dowsing.com/goods/baketan/)によると、以下のように書かれています。
> ごく簡単に説明すると、サイコロを、８回振り、特定の数字に偏りが出ると赤、ランダムに全ての目が出れば、青が光る様に作られています。
> 
> 0～5の数字をランダムに発生させ、カウントします。
> 
> 0～5が綺麗に揃ってカウントされれば、良い影響があるとして青が光ります。
> 
> 0～5の特定の数字に偏りが出て、統計上、誤差以上の偏りになったときに、悪い影響があるとして、赤が光ります。

一方、[NMR ねとらぼミステリー調査班](https://nlab.itmedia.co.jp/nl/articles/2005/18/news106.html)では以下のように書かれており、秩序ある目の出方についての書き方が微妙に異なっています。
> 統計上の誤差以上の偏りがなければ、緑（正常）。青緑や青（良い反応）はちょっと特殊で、例えが変わりますが、サイコロを振って「123456」みたいに、なんらかの秩序がある結果のとき。

~~**プログラム内部で１から6までの目のサイコロを8回振ることでお化け探知をしているいると考えてよさそうです。**~~

上記の記事から1から6までの数字を8回ランダムに生成していると読めますが、実際の動作を見るとサーチモード作動中は8色に変化しているので **1から8までの数字をランダムに8回生成している** と考えたほうがよさそうです。実際、バイナリで数字を生成する場合には6という数字は中途半端なので 2^3=8 ということで、8種類の数字を出していると考えたほうが自然です。

### お化け探知について2
1,2,3,4,5,6のような秩序ある結果が出た時には「良い反応」、偏った結果が出た時には「悪い反応」らしいのですが、実際どういう目が出ると秩序があるのか、偏ると悪い反応なのかについての具体的なデータがないのでわかりません。
しかしながら、[日本ダウザー協会](https://www.j-dowsing.com/goods/baketan/)では[ＧＣＰ(グローバル.コンシャスネス.プロジェクト)](http://www.global-mind.org)について言及しており、[同ページの結果](http://www.global-mind.org/results.html)を見てみると[ランダム・ウォーク](https://ja.wikipedia.org/wiki/ランダム・ウォーク理論)からのずれを使って異常現象を検出しているように見えます。イメージとしては[このサイト](https://azoay.hatenablog.com/entry/2015/06/25/213839)が分かりやすいかも。
また、[NMR ねとらぼミステリー調査班](https://nlab.itmedia.co.jp/nl/articles/2005/18/news106_2.html)では以下のように述べられています。
> **河原**　「0」「1」をそれぞれ1/2の確率で出しているとして、それを100回繰り返せば0と1が50回ずつ出るはずですよね。これが統計上の誤差以上の偏り……1がやたら多かったとか、1しか出なかったとかですね、そういうときに黄色や赤（おばけ反応）が出ます。
> 
> 　統計上の誤差以上の偏りがなければ、緑（正常）。青緑や青（良い反応）はちょっと特殊で、例えが変わりますが、サイコロを振って「123456」みたいに、なんらかの秩序がある結果のとき。
> 
> 　本当に不思議なんですが、心霊スポットでは乱数が偏る傾向が、パワースポットでは乱数が整う傾向があって……各種スポットの解析データにそう出ているんですよ。

なので、「お化け探知について」で書いた話とは矛盾しますが、判断基準として1－6または1－8までの数字ではなく、0または1の目を使ったランダム・ウォークを行いるほうが判断が簡単そうです。8つの目のサイコロを8回振っているらしい動作をしているらしい観察結果を踏まえ、3bit (1－8の目) の試行を8回つまり24回分のコイントス・データを使ったランダム・ウォークを行うのがよさそうです。
ランダム・ウォークの結果として期待されるよりも著しく上または下に行った場合には「お化け反応」があるとして赤を表示、ゼロに近い位置をうろうろしていた場合には 0101... や 000111... などのそろった目が多く出ていると判断して「良い反応」と判断したいと思います。

### バリアモードについて
[NMR ねとらぼミステリー調査班](https://nlab.itmedia.co.jp/nl/articles/2005/18/news106.html)では
> バリアモードを発動すると、緑色となる数字を強制的に一定時間吐き出し続けます。これは「乱数がおかしい＝おばけがいて、乱数に干渉している」のだから、「乱数を正常にする＝おばけがいなくなる、乱数に干渉できなくなる」という発想です。

と書かれています。[日本ダウザー協会](https://www.j-dowsing.com/goods/baketan/)によると、バリアモードは約10分続き、その間は統計的偏りがなくなるので緑色にしか光らなくなるそうです。

# 再発明を目指して
## ハードウエア
購入した実物を見る限り基板上のアンテナっぽいパターン以外センサーらしいものは見えません。「基盤のアンテナで **電磁波** や **静電気** 、 **音圧変化** などを受信し」と書いてあるところを見ると、本体底部の圧電スピーカーも「霊界アンテナ」の役割をしているのではないかと思います。圧電スピーカーは振動を電圧変化に変換してくれますし、インピーダンスが高いので、電磁シールドをしない状態の圧電スピーカーの電圧を測定すると静電気や外来ノイズも拾ってくれます。つまり、上記の **電磁波** や **静電気** 、 **音圧変化** がごちゃ混ぜになったデータを取得することができます。アンテナは4つ搭載されていると書かれていますので、表裏のアンテナっぽいパターン、圧電スピーカーでアンテナ三つ分になりそうです。「霊界アンテナ」がもう一つ足りていませんが、可能性としては実装されているトランジスタをノイズジェネレータ、実装されているダイオードが発生するノイズ、スイッチを押すタイミングが候補として挙げられます。
とりあえず、「再発明品」の霊界アンテナには圧電スピーカーと、端子の浮動電圧を使用したいと思います。
疑似乱数を発生させるなどそこそこ高度な処理をしているのでマイコンの使用は必須です。とりあえず手元にある[Arduino Nano互換ボード](https://amzn.to/3NwVh4x)を使って開発しようと思っています。

## ソフトウエア
### 乱数の発生
1個3000円程度で売られている装置なので、あまり~~複雑な~~重い疑似乱数アルゴリズムが使われているとは思えません。疑似乱数アルゴリズムとしては[線形帰還シフトレジスタ](https://ja.wikipedia.org/wiki/線形帰還シフトレジスタ)を使ってM系列疑似乱数を発生させているのではないかと思います。
ボタンを押したときの動作を見ると、不定期な間隔で色が変化するので、M系列疑似乱数を使って圧電スピーカーの電圧を測るタイミングを決めていると推察されます。電圧測定値の下位１ビット（つまり測定電圧を２で割った剰余）を3回測定した結果をLEDの色で表示しているのではないかと思います。M系列の初期値はどうしているか？電源を入れた時の電圧値あたりを使えばいいのではないでしょうか。

## 最小構成用ソースコード
お待たせしました。やっとプログラムできました。
まずはアナログ入力の浮動電圧から乱数を取得してArduinoのシリアルプロッタで結果を見てゆきます。
アナログ入力のところに圧電スピーカーをつなげるともっと本格的になると思いますが、今日は外付け部品を何もつけずに動かします。
```C++:baketan_homage_32bit_serial.ino
#define MSEQ_WIDTH 40
#define BYTES  4
#define sensorPin A0  // センサーピンの場所

const unsigned int one=1; // ビット演算のための定数
unsigned int sensorValue;
unsigned long Xn;
union {
  unsigned long int sum=0;
  unsigned char div[BYTES];
} data;

void setup() {
  unsigned int i;
  for(i=0; i<BYTES*8; i++){
    data.sum <<=1;
    data.sum |=i % 2;
  }

  Serial.begin( 9600 ); 
  Xn = analogRead(sensorPin); // M系列乱数のための初期値をアナログ入力から挿入
}

void loop() {
  unsigned char r=mseq();
  unsigned char i;
  unsigned char wait;
  unsigned char parity;
  unsigned char popcount;
  /* M系列ノイズの01列を8ビット整数に変換 */
  for(i=0, wait=0; i<8; i++){
    wait*=2;
    wait+=mseq();
  }
  /* ランダムな時間待つ */
  delay(wait*3);

  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  parity=sensorValue & one; // sensorValue % 2 と同義。センサ値の偶奇性を取得
  //parity=1; // デバック用

  // 01情報をdataに蓄積してゆく
  data.sum <<=1;
  data.div[0] |=parity;
  // 1の数を数える
  for(i=0, popcount=0; i<BYTES; i++){
    popcount+=__builtin_popcount(data.div[i]);
  }
  Serial.print(popcount-BYTES*4); // BYTES * 8 個分の乱数の偏り
  Serial.print(", ");
  Serial.print(__builtin_popcount(data.div[0])-4); // 直近 8 個分の乱数の偏り
  Serial.print("\n");
}

// M系列の変換
char mseq(){
  // シフトレジスタ
  //static unsigned long Xn = 'b';
  unsigned ret;

  ret = ((Xn & 16384) >> 14) ^ (Xn & 1);
  Xn = (Xn << 1) + ret;

  return ret;
}
```

## 結果
Arduino Nanoに外付け部品を何もつけずにUSBでPCにつなぎ、シリアルプロッタで観察した時の結果を下のグラフに示します。
青い線が直近32個分の乱数の偏り、赤い線が直近8個分の乱数を示しています。ゼロに近いほど期待値に近く、上または下に行くほど出る目が偏っていることになります。青い線がプラスまたはマイナス16まで行くとそれぞれ32個の乱数のすべてが１またはゼロでそろっていることになります。お示ししたグラフだとせいぜい-9くらいまでしか行っていないので、偏りはそれほど大きくなく、お化けは来ていないと思います。
「良い反応」は010101などのような規則性のある数列ということなので、グラフでいえばゼロ付近の時が良い反応に当たると思います。ただし、グラフがプラスからマイナスに動くときは必ずゼロ付近を通過するので、別の定義を考える必要がありそうです。
![画像_2022-07-19_021738438.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199416/93285369-4451-67f8-7236-f5ef328bdc17.png)

できた最小構成を数時間走らせていて気が付いたのは、端子に負電圧がかかっていると取得される値が常にゼロになってしまい乱数発生装置として機能しなくなることが分かりました。静電気対策が必要です。

# 今日はここまで
眠くなってきたのは今日はここまでにします。
[次の記事](https://qiita.com/uhmin/items/89b6ce1e0173750d3ed1)で「良い反応」の定義やLCDを追加したバージョンを作りました。