2021年10月7日木曜日

ダイソーのソーラー・ガーデン・ライトのキャンドル化 Make flickering lantern from cheap solar garden light

 吊るソーラー・ライトに引き続き、同じく100円で売られている「ソーラー・ガーデン・ライト」をカラーキャンドル化した。これは前出の吊るガーデンライトに比べ角が尖ったままの形状である。太陽電池は4cm×4cmと吊るソーラー・ライトと同じ大きさである。



本体は吊るソーラー・ライトとほぼ同じような構造であるが電池ホルダーが作り込んでありネジを外さなくても電池を交換できるようになっている点、及び下部にピラミッド型の反射板があって水平方向に光を散乱できるのは良い。

残念な点は、 吊るソーラーライトと同じ値段でありながらこちらが部品点数が多いためか仕上げが雑な点が気になる。全部で8個買ったが1個は太陽電池が浮いてガラスのエッジが出て危ない状態だったので交換してもらった。はんだ付けも雑である。吊り下げる部分がプラスチックなため、紫外線で劣化して日が経つと落下しないか気になるところである(強風に耐えられくて落下する事がある事はその後経験済み)。



使っているICが YX8018B で吊るソーラー・ライトとは配線図が少し違うが基本は同じである。またL1の値が違うほか、消費電流が約5mAと吊るソーラー・ライトの半分以下なので省エネになっている。この理由は、昇圧回路のスイッチング周波数がカタログ上YX805Fの100~250KHzに対しYX8018Bが200~340KHzと高く、そのぶん高効率になっている事だと思われる。ちなみにジャック・オ・ランタンで使ったCL0116のスイッチング周波数はカタログ上100KHzになっておりYX805Fと同様なのだろう。


これを次のように改造した。吊るソーラー・ライトと同じく基板のパターンを1ヵ所切断する必要があった。


 この回路で緑と青のライトを作ったが青色LEDは暗かったのでL1を100μHに変更した。このとき緑の消費電流は4.5mA、青が10.5mAであった。

 

 これまで使ってきたLEDは適当に選んだもので必ずしも目的に合ったものでない。本件に関係するLEDの仕様項目には光量(及び順方向電流If)、半値角、順方向電圧降下(Vf)等があり、標準的な電流(If=20mA)に於いて出来るだけ明るく、また半値角が広い物が望ましい。

改めて秋月のWEBから適切そうなLEDを選んで実装してみた(次表参照)。

黄緑については適当な光量のLEDが見つからなかった。また紫(紫外線)は電流を増やし(L1の値を減らし)ても可視光は暗く、本ライトには不向きのようだ。

変更したL1を元の値に戻し、これらのLEDを使ったライトを作成して物干しに並べてみた。

 なおこの中の奥の方にあり色の変化している1個は次回に説明するRGB-LEDを使った物だ。

IC保護などを考慮した最終的な回路を次のようにした。

C2の電圧を観測したところでは保護用のD2は必ずしも必要ないようだ。


 

2021年10月2日土曜日

ジャック・オ・ランタン(Jack O'Lantern) のLEDキャンドル化 Add flickering function for LED in my Jack O'Lantern

 2年ほど前に置物のジャック・オ・ランタンにLEDランプを仕込んだ。

今回、このLEDをキャンドル化した。手法は前回のソーラーライトのキャンドル化と同じである。回路図は次の通り。白丸より左は従来のソーラーライトの基板をそのまま流用して作成している。白丸より右をユニバーサル基板に組み込んでジャック・オ・ランタンの中に仕込んだ。

L1を330μHから68μHに替えたことで消費電流が13mAから55mA程度に増加した。


ここまで出来たので、改めて秋月で入手可能な部品を使って全てを新しく組み立ててみた。

IC1にはCL0116を使った。YX805Fとはピンコンパチブルであるが昼夜の識別レベルが少し異なるようである。


キャンドル駆動ICはOSCDIC6441とは別にCDT3460というICのも売っていて互いにピンコンパチブルであるが、これらで駆動したLEDの光り方を比べたところCDT3460は揺らぎが単調なのでOSCDIC6441を採用した。CDT3460が無風状態の仏壇の蝋燭、OSCDIC6441が風の中の蝋燭といった雰囲気である。次の動画で左がCDT3460、右がOSCDIC6441の明滅である(左のLEDは3mm黄色、右は5mm蝋燭色)。

また手持ちの赤色LEDでは暗かったので、高輝度で指向性の緩い(半値幅が広い)LED(OS5RPM5B61A)に交換した。

 L1についてはLEDの種類や夜間の周囲の明るさ、電池の持ちを加味して4つの値(47μH,100μH,220μH,330μH)から選べるようにした。これらを試したところ220μHより小さくしても消費電流が増えるだけでLEDはあまり明るくならないので、現状では220μHが良いようである。ちなみにこの時の点灯時の消費電流は15.5mAであった。消費電流の増加を見込んで太陽電池に少し大きなものを使い、NiMH電池は単3にした。

これを玄関に置いてみたが照明に負けない明るさがある。

 

玄関は北向きで直射日光は射さないがランタンは毎日朝まで光っている。

2021年9月26日日曜日

ダイソーの「吊るソーラーライト」をキャンドル化する Make flickering lantern from cheap solar light

ダイソーで100円の「吊るソーラーライト」を買った。

上面に太陽電池が張り付けてある。 昼間に太陽電池でニッケル水素電池(NiMH)を充電し、夜間はこの電力を使って発光ダイオード(LED)を点灯するものである。日が暮れて太陽電池の出力電圧が低下すると夜間モードになりLEDを点灯させるようになっている。 
このライトを選んだ理由は上面の太陽電池が4cm×4cmと100円のわりに他のライトより大きかったからである。

全体は上下に分かれ、上部(蓋に相当)が機能が集約された本体であり、下部は模様が透かし彫りで刻まれた箱である。

ソーラーライト本体はネジ4本を緩めることで簡単に分解できる。中には簡単な片面基板と単4ニッケル水素電池が入っている。

回路をトレースしてみると次のようなものである。

回路はYX805Fという4本足のICを中心に構成され、このICで全てを制御している。このICは太陽電池の電力をニッケル水素電池に充電するとともに、太陽電池の起電力が低下すると夜モードに切り替わりLEDを点灯させる。実測すると太陽電池の起電力が約0.4V以下になると夜間モードに切り替わるようである。さらにスイッチング方式の昇圧器を備え、Vf(順方向電圧降下)が3V位あるLEDを1.2Vの電池で駆動する機能を持っている。

 この回路を、秋月で売ってるキャンドル駆動IC(OSCDIC6441)を用いて次のように改造した。

IC2がキャンドル駆動用ICである。このICのVDDに2~5Vの電圧(LEDのVfより高い必要がある)を加えるとLED端子に接続したLEDの光をキャンドルのように揺らめかせる(明滅させる)ことができる。D1とC1は平滑回路で、IC1で作った駆動用電圧(パルス)を平滑化し直流にしてIC2に供給している。D1には順方向電圧降下の少ないショットキーダイオードを使うのが良いが私は手持ちの普通のシリコンダイオードを使った。回路のスイッチング周波数が数百KHzと高いのでC1には周波数特性の良い積層セラミックコンデンサを使った。

改造は、LEDを好きな色に交換し、基板のパターンを1か所カットし、3個の部品を取り付けるだけで済む。

この回路を組んで何色かのLEDを付けて比べてみた。次の動画で右端はオリジナルのソーラーライトで、それ以外は改造品(左から緑、蝋燭色、赤、青)である。

赤色のLEDが思いのほか暗い。これは使った赤色LEDの光量が少ないためだと考えられる。その対策として赤色LEDを2個直列にしたら次の動画のように少し明るくなった。赤色LEDは電圧降下(Vf)が少ないため2個直列でも光らせることができ、その場合でも消費電流は何故か増えなかった。

 

ライトの明るさはLEDの電流と発光効率に依存するので良く光るLEDを選んだほうが良い。緑のLEDは他と比べて明るいが、これはLEDのデータシートによると他に比べ光量が約3倍あるようである。またL1の値を変更することで電流を制御することができるが、電流を増やすと当然電池の「持ち」も悪くなる。YM805Fのマニュアルを探す事が出来なかったので代わりにYM805Aのマニュアルにある定数を見ると次の様になっている。

私の使ったLEDでは青と黄色が暗かったので、これらのL1を220μHに変更した(消費電流が2割ほど増加した)。

回路の消費電流の実測値は12mA程度であり内蔵のHiMH電池が表記通りの容量(100mAh)だとしてもフル充電で8時間しか持たず朝まで光らせる力はない。これを国産品の750mAhのものに交換して一晩持つようにする事ができた。

 とりあえず8個ほど作ってベランダの物干しに吊るしてみた。

LEDには指向性があり下向きに取り付けているため(使ったLEDの半値幅は60度~70度)光が出来るだけ水平方向に拡散するようランタンの中に縮れさせたアルミホイルを丸めて入れている。

なお秋月ではLEDに被せるキャップを扱っているので、(好みによっては)それを使って光を拡散させるのも良いだろう。 

キャンドル駆動用IC OSCDIC6441(IC2)の入力電圧の絶対定格は5.5Vであるが、LEDが消灯している瞬間はこれを超えピークで7~8Vになる。(実際、制作の途中で何個かOSCDIC6441を壊した)IC2を壊したくない場合はC1と並列にLEDのVfより少し高い電圧(色にもよるが概ね3.6V程度)のツェナーダイオードを入れると良い。

また何らかの要因でLEDがほとんどチラつかない場合がある。とくに悪天などで充電不足となり電池が消耗して電圧が下がった場合に顕著のようである。これはC1と並列に100uF程度の電解コンデンサを入れて直流を安定化させると改善されるようだ。

これらの修正を加えた回路は次のようになる。


この図ではD2の位置が上に述べた場所と違うが、同じ効果が得られ、またこの方がIC1の過電圧保護にもなるだろう。ただ、C2を入れることでピーク電圧が抑えられ電圧が安定するのでD2は必ずしも必要ないようだ。

【不具合】色々テストしている間にキャンドル駆動用IC OSCDIC6441には次のような不具合がある事が分かった。即ちVDD端子に10mV程度の電圧を加えた後その電圧を上昇させてもLED端子に接続されたLEDは光らない。この現象で一見OSCDIC6441が壊れたように見えるが電圧をかけずに放っておくと復活している。ソーラーライトでこの不具合が発現するのは電源SWがOFFの状態で太陽電池に弱い光が当たってる場合や曇り続きでNiHM電池が消耗した時である。

これを復活させるには、
(1)もし電池が消耗している場合はスイッチをONして数時間太陽光に当て、NiHM電池を充電する。
(2)その後太陽電池を覆った状態でスイッチをOFFにしてそのまま暫く放置しておき、その後太陽電池を覆った状態で電源をONにする。

復活するまで(2)を繰り返す。
別の方法としてOSCDIC6441のVDD端子に(テスターの抵抗計などで)弱いマイナスの電圧をかけてやると直ぐ復活するがその為にはソーラーライトを一度分解する必要がある。

【その後】1年ほど使ってみたが、やはり防水がキチッとしておあらずいくつか問題が発生した。まず(1)ソーラセルの周囲から雨水が侵入してソーラーセルの電極辺りが腐食したものが出てきた。防水するために一度ソーラーセルを取り外したいが接着されていて力を入れたら割ってしまって諦めた。仕方ないのでソーラーセルの周囲を紫外線硬化樹脂で埋めてみた。(2)電源スイッチが錆びてきた。これは CRC 2-26 をスプレーするくらいしか対応はない。(3)LEDを出っ張って取り付けていたがLEDの付け根がU字に凹んでいてここに水が溜まり電極の付け根を腐食させた。これもLEDの付け根を紫外線硬化樹脂で埋めるとともに、基板からあまり突出させないよう取り付け直し、ケースとLEDの隙間も紫外線硬化樹脂で埋めた。 


2020年12月29日火曜日

遅ればせながらPIC手習い(その3)

  さて、話をプログラミングに戻そう。

 PICを使う上で最も重要なのはpinの使い方だ。全体を眺めると、20pin以下のPICの場合、刻印のある1番pinはVdd、上から見て反時計周りに最後のpinがVssになっているようだ。 他のpinには色々な信号を割り付ける事が出来るようになっている。

 16F18346の場合教本(英文マニュアル)のTable3に信号の一覧表がある。例えば一番上の(20pin-PDIPパッケージで)19番pinの場合デジタル入出力の名前はRA0、つまりAレジスタのビット0である。このpinには他にデフォルトでADコンバータのANA0(A0入力)、或いはDAコンバータの出力(DAC1OUT)等が割り付けられている。

また次のようにpinにデフォルトで割り付けられていない信号も存在する。

  このような信号とpinの割り付けをコントロールするのが内蔵されてるPPS(peripheral pin select)モジュールだ。16F18346の場合使えるポートはA,B,Cの3つである。ただし各ポート毎に全8ビットが使える訳ではなく、実際に16F18346で使えるのはA0~A5、B4~B7、C0~C7のみである。これらはそのままデジタル入出力の信号名RAn、RBn、RCn(nはビットを表す数字)に対応し、電源を除く18本のpinに割り振られている。これが次図である。


 各々のpinをデジタルで使うのかアナログで使うのかを決めるのがPPSのANSELxレジスタである(xはA,B,Cの何れか)。自分が使いたいモジュールの信号がデジタルなのかアナログなのかはマニュアルのTable1-3にある。ANSELxレジスタの対応するビットが1の端子はアナログ、0の端子はデジタル入出力となる。
 デジタル入出力の場合、TRISxレジスタでその端子が入力か出力かを指定する。もしアナログで使う場合はTRISxの対応するビットも1とする。つまりビット単位で次の設定を行うことになる。

 これらのレジスタをC言語でビット単位に扱うにはレジスタ名に「bits」を付けドットを付けた後にビット位置を表す定数名を書く。この定数名はレジスタ名+数字と同じではない場合もあるのでMPLABのプログラム編集画面では示される候補の中から選択すればよい。例えば3番pin(RA4)をデジタル入力に使うためには ANSELAbits.ANSA4=0、TRISAbits.TRISA4=1 とする。また ANSELA=0b10101010、TRISA=0b01010101 のようにレジスタの全ビットを同時に書き込む書き方もできる。

 機能をpinに割り振るためには、ANSELxレジスタとTRISxレジスタの対応するビットを指定する他、どの機能(モジュール)をどのpinに割り振るか指定する必要がある。これは実際には次のように sssPPS或いはRxnPPSのレジスタで指定する。

  • sssPPS  = pin番号  (入力の場合)
  • RxnPPS = 信号番号  (出力の場合)

 入力の場合、左辺のsssは前述のTable3に書いてある信号名、出力の場合のRxnはRC4の様なデジタルのpin名である。 右辺のpin数(実際のpinの番号ではない)や信号番号は英文マニュアルの13.8節のREGISTER 13-1, 13-2 に説明されているが英文なので慣れないと取り付きが悪い(割り付けの変更が出来ない信号もあるようである)。例えばRC7をUARTの出力、RC6をUARTの入力と定義したい場合は、
    RXPPS   = 0b10110;       //RX input is RC6
    RC7PPS = 0b10100;       //RC7 source is TX
 と記述する。

 以上のようにあるpinにある機能を割り付けるのに通常3つのレジスタに値を設定する必要がある。 例外としてデジタルの入出力を直接ソフトで扱う場合(例えばLEDを点滅する場合やスイッチのON/OFFの検知など)はANSELx、TRISxの2つを設定するだけで済む。

 pinの割り付けが済んで、初めてPICに内蔵される機能を使う事ができる。 

(つづく)


2020年12月20日日曜日

遅ればせながらPIC手習い(その2)

  目標としている回路はLEDで光を出し、その光をフォト検出器(トランジスタ)(PD)で受光し、その比を求める機械である。光の通し方によって透過型や反射型、散乱型など考えられるが回路的には同じで良いと考える(もし受光量が微弱であればロックインアンプを使う事も考える必要がある)。

 LEDの光量は電流値にほぼ比例する。またPDも受光量に比例した電流が得られる。そこでD/Aコンバータの出力電圧でLEDを電流駆動するとともに、PDに流れる電流を電圧に変換してA/Dコンバータに取り込む回路が必要である。PICのD/Aコンバータの外部回路の駆動能力は低いので高インピーダンスで受ける必要がある。またA/Dコンバータの入力インピーダンスも高くないので低インピーダンスで電圧を与える必要がある。いくつか試した後、次の回路に落ち着いた。 

 IC2は単電源のフルスイング汎用OPアンプであり、秋月で売ってるJRCのNJU7043Dを使った。Tr1はジャンク箱に転がっていた普通のNPNトランジスタ(2SC641)で、エミッタフォロワーで電流増幅に使っている。PIC 16F18346のD/Aコンバータの出力はデフォルトの19番pinに出力する。R1とLEDは直列に接続しているのでLEDにはR1と同じ電流が流れる。R1は電流を電圧に変換するための抵抗で、この電圧がD/Aコンバータの出力と同じになるようOPアンプに負帰還をかけている。

 R1の電圧はPICの16番pinからA/Dコンバータに取り込んでLEDの電流をモニターできるようにしている。

 R2はPDの出力電流を電圧に変換する。この電圧はOPアンプによる高インピーダンスのボルテージフォロワーで受けてPICの15番pinからA/Dコンバータに渡している。R2の値は取り扱う光量とフォトトランジスタの性能で決める。感度が足りなければPDをダーリントン接続にするとよい。

 D/Aコンバータの出力電圧をVdaとするとR1及びLEDに流れる電流Iledは Iled=Vda/R1である。このときTr1のエミッタ電圧VeはLEDの順方向電圧降下をVfとすると Ve=Vda+Vf となる。またベース電圧VbはTr1のベースエミッタ間の電圧をVbeとして、Vb= Vda+Vf+Vbe である。OPアンプとTr1のベースは直結しているからOPアンプの出力電圧Vop=Vbである。すなわちVop= Vda+Vf+Vbe という関係が成立する。
 OPアンプの最大出力電圧Vophを4.9V、Vbeを0.7Vとすると、4.9 = Vda+Vf+0.7、すなわち Vdah=4.2-Vf がこの回路が機能するD/Aコンバータの最大出力電圧である。このときLEDにIldehの電流を流すためにはR1の値は、R1=Vdah/Iledh とする必要がある。一般的にIldehは20mA(0.02A)である。
 もし赤色や赤外LED(Vf=1.2V)を使うとすると、Vdahは3.0Vとなり、R1は150Ωとなる。また白色LED(Vf=3.2V)を使うとVdahは1.0VでR1は50Ωとなる。

 このようにPDのLEDに順方向電圧降下Vfの大きい青や白色LEDを使う場合この回路ではダイナミックレンジが狭まるのでTr1をPNP型に替えたほうが良いかもしれない。この場合Tr1のEとCを逆に接続、さらにOPアンプの入力の+/-を逆にする(次図参照)。仮に順方向電圧降下が3.2V/20mAのLEDを使う場合R1は50Ω程度となる。またR9は20KΩ程度である。

 

 ちなみにI2Cを使った液晶表示器(LCD)との接続は次のように簡単である。液晶は秋月で売ってる AE-AQM1602A(16文字×2行)を使った。I2Cの信号線は複数のデバイスが接続できるバス形式のワイヤードOR接続である。従ってプルアップ抵抗が必要であり、LCD補助基板内のプルアップ抵抗を半田付けでONにしている。

 一応ソフトが上手く動くようになったので、ユニバーサル基板に組み上げた(写真は追加回路を含む)。


このとき電池駆動する事が前提なので3端子レギュレータを使った簡単な電源回路を組み込んだ。

 この回路の消費電流はせいぜい十数mAなので電源に20V程度を供給してもTO-92パッケージの小型3端子レギュレータの定格を超えない。さらに電池駆動を前提として電源電圧の監視回路を組み込んだ。具体的には電源電圧をR7とR8で分圧してA/Dコンバータに与えている。抵抗で分圧するのは 電源電圧が高くなってもA/Dコンバータの入力電圧がA/Dコンバータの上側の参照電圧(Vref+、約4Vに設定)以下に収まるようにするためである。

 最後に、ユーザインターフェイスとして次のような回路を組んだ。

 これらは動作確認用LEDとスイッチ及びジャンパーである。これらはソフトで機能を設定することで自由に使える。

(つづく)
 





2020年12月18日金曜日

遅ればせながらPIC手習い(その1)

 知人に頼まれた機械をどう作るか考えていたら、PICが良いんじゃないかというアイデアに辿り着いた。PICという名前やCPUやメモリ、様々な周辺回路が1つのICチップに内蔵されていて百円程度という夢のような値段で入手できる事は以前から知っており、PICの見本として八潮の秋月で適当に見繕って8pinと14pinの安いPICを買った以外は未だ手を出したことが無い。もちろんライター(プログラムの書き込み器)も持ち合わせていなかった。

 情報を得ようとネットで検索するとPICにはものすごく多くの種類があることが分かり、CPUのビット巾だけでも8ビットから32ビットまである。内蔵する周辺回路もてんこ盛りでかなり複雑に出来ている。私が半世紀近く前に卒論に使ったインテルの8080で同じものをディスクリートで組んだらラック1つを占有するだろう。こんなものが百円程度で買えるとはすごい世の中になったものである。一方こんなアナログとデジタルが混在した複雑なものを僅か8ピンや14ピン程度のICにどうやって押し込んでいるのか謎である。

 PICには通常OSや外部記憶の様なものはなく、プログラムをPICに直書きして動かす。プログラムの開発環境としてはPICの製造元の Microchip Technology 社がMPLAB X IDEというソフトを無償で提供しており、アセンブラやCで書けるようになっている。

 どのPICを使うにしてもライターは必須であるが、これも Microchip Technology 社がPickitという名前で販売しているほか中華製のコピーもあり、秋月電子でも独自に開発したPicKit2の互換品を売っている。ただPicKit2はデザインが古くMPLABではもはやサポートせずWindows10にも対応していないようなので(何故かいまだに秋月で売っている)今後の事を考え最新型のPicKit4を買った。PicKit4にPICを付けるアダプタは簡単なので、とりあえず必要な20pinのものを自作した。要はPicKitの5本の線を決まった足に直接接続するだけで20pin以下のPICには対応できるようだ。

 これでネットで出回っているLEDを点滅させる簡単なプログラム(バージョンが古いのかコンパイルエラーとなり少し修正する必要があった)を、昔見本として買っていた14pinのPIC 16F1823に書き込んで、ブレッドボードで組んだ回路で動かしてみると簡単に動いた。 プログラム本体は次のようなものだ。

     while(1){
        RA2 = 1;
        __delay_ms(100);
        RA2 = 0;
        __delay_ms(100);
    }

しかし、その前段階としての念仏が多い。例えば、

#pragma config FOSC = INTOSC
#pragma config WDTE = OFF

     OSCCON = 0x00;
     TRISA  = 0x00;

といった書き方で、これはPICの初期設定だったり、ハードウェアの操作であったりする訳であるが、ここに登場する大文字の名前がプログラム中には定義されておらず、ある意味仲間内での秘密の呪文であり私みたいな異教徒には理解できない言葉である(実際には#include文を辿っていけば発見できるかもしれないが、そこには値は定義されていても意味は含まれていない)。しかし、これらを知らないとPICのプログラミングは不可能。
 これを身に着けPIC教徒の洗礼を受けるには経典を読むしかない、ということでAmazonを彷徨って経典を探した。PICに関する経典は古いものが多く最新の情報が全般的に得られそうなものは少ない。とりあえず「C言語によるPICプログラミング大全」という経典を得た。これも元は改訂版が2009年という古いもののようであるが、2018年にリニューアルされ、さらにネットで2020年の最新情報が提供されている。

 これを手元に大航海に出た。 次の目標は16F18346を使ったとある回路である。この16F18346は20pinのICであり電源を除く18pinをプログラミングにより色々な目的に使うことが出来る。

 

 16F18346を使う理由はI2Cインターフェイスを持ちLCDと簡単に接続できてお勧めとのネット記事を見かけたからである。それにA/DやD/Aコンバータを内蔵しており、メモリーもそこそこあり目的には十分である。おまけに秋月で1個160円と安い。内部の構成は次のようになっている。


 とりあえず、ブレッドボードで組んでネット情報の再現を試みた。

  そこで分かったのは、私が買った経典は数多くあるPICの一般的な使い方について書いてあるが個々のPICの方言には対応していないという事である。LEDチカチカやLCD表示程度はネットで得た情報で何とかなったがそれでは応用が効かない。こうなったら原典に当たるしかない。

 そこでMicrochipから16F18346のマニュアル(PDF)をダウンロードした。英文でなんと500ページある。1ページ10円のコンビニ印刷でも全部印刷したら5千円!!!、160円のPICを使うのにこんなに経費がかかるとは。
 とりあえず必要そうな部分300ページ程を印刷した。

 (つづく)

 

2020年3月4日水曜日

ロト6は攻略できるか(その3)

 前回はロト6の当選数字のパターンを色々調べて出現傾向を調べてみた。実は昨年8月、数年ぶりに何となく買ったロト6が4等に当たり(それから助平根性が出て)その4等を原資として時々買い、その後暫くはあまり原資を減らすことなく買い続けることが出来たが10月頃に数字の出方が変わったようで全く当たらなくなり、11月に原資が底を突いた。
 そこで前からやりたかったAIによる予測に挑戦してみる事とした。いわゆる Deep Learning である。数年前に興味があって買った Deep Learning の本(Pythonで記述)が積読になっていたので、改めてこれを読んでロト6の Deep Learning に挑んた。残念ながら私はPythonは不慣れだしバグ大好きの弱い型付けの言語は嫌いなので同じような流れをFortranで書いてみた。
 Deep Learning の処理は Y=f(W*X+B) という基本演算で構成される。Xが入力でありYが出力 、Wが重み、Bがバイアスで、Wが2次元配列、Y,X,Bは1次元配列、fが非線形の出力関数である。WとBが任意パラメータで、これらの値が学習内容に相当する。この基本演算を複数層直列に積み上げることでAIを構成する(Wikipediaによると4層以上ないと Deep Learning とは言わないらしいが、以下は爺の手習いということで勘弁してもらいたい)。
 第1層の入力X1がAIの入力であり最終層の出力YnがAIの出力である。ロト6の場合X1は学習や予測に使う過去の抽選結果であり、その大きさは学習に使うデータ数(=抽選回数)×43、Ynは各数字の出現確率を表す43個の数値とした。1層のみのDeepLearning は単なるx元1次連立方程式の最適パラメータ決定になる。基本演算を2段以上積み重ねると層間に外部には出ない接続 Ym⇒Xm+1(隠れ層)が出来る。
 学習を行うためには最終的な演算結果(output)と真値(truth)の差(誤差、loss)をフィードバックしWとBの値を修正するカラクリが必要であり、誤差を 微分(dX/dY)的な係数を掛けながら処理とは逆方向に伝搬させ、係数(学習率?)を掛けてWやBを修正する。WやBの初期値には乱数を入れている。

 幸いな事にPythonで配列を計算するライブラリー(NumPy)がFortranの配列演算と相性が良いので助かった。出来上がったプログラムは全部で800行程度であるが、Deep Learning の処理自体は100行程度だろう。層数や隠れ層の幅、学習率は任意パラメータとしている。

 実際に2層の Deep Learning、隠れ層を100にしてロト6の過去データ(ボーナス数字を含む7つの数字)を読み込ませると、あっという間に過去データを学習し100%正解できるようになった。じっさい高々1500回にもならない過去データではAIと言うほどの性能も必要無いようだ。しかし過去データの最後の部分を隠して予想させてみるとこれが全く当たらない。次図は第1459回までのデータを使ったとある結果である(**が当たった数字)。

  ここで過去データを Deep Learning のやり方に従って学習データと評価データに分け、 学習データで学習させた後で評価データを評価してみた。そうすると繰り返し回数を多くして学習を進めるほど評価は悪化する。いわゆる過学習の状態なのだろう。ロト6は原理的にランダムな現象なので当然と言えば当然である。
 何回も試しているうちに、乱数による初期設定を変更しても隠れ層の幅を変更しても結果の傾向はあまり変わらない事に気づいた。簡単な Deep Learning でも過去のデータは十分学習できて方向性を持った予想を出せるようである(ただし予想結果は現実とは合っていないが)。次表は第1459回までのデータを使って色々パラメータを変えながら第1460回を予想した結果である(黄色マーカが本数字、緑はボーナス数字)。値は確率(%)を表す(水平方向の合計値はボーナス数字を含んでいて約700%になる。##は100%を超えた値)。

 3層の Deep Learning は学習に時間がかかる。2層だと50回も繰り返せば概ね安定するが3層だと収束するまで1桁上の学習が必要のようである。直近の予想確率例と抽選結果は次のようなもので当たるも八卦当たらぬも八卦といった所である。
(3層100回学習の結果)

 4層の(本来の)Deep Learning も試してみた。ある回の当選番号とその直前50回分との関係を全てのデータで500回ほど学習させ次回を予想する、これを初期値を変えて10回行い結果を平均してみたが、これには私のCore i5-9600K(3.7GHz)で80分ほどかかり、以下の表を作成するだけで計17時間以上かかった。この表では平均値(16.3)より大きい数字は赤色で表示している。理想的には100%の数字が7つあり他が0%なら完璧に予想出来ている訳であるが、結果を見ると予想出来ているとは言い難い。実際の抽選では必ずしも予想確率の高い赤い数字が選択されておらず、回によって確率が平均より大きいか小さいかに偏った数字が選択されている場合が多いように見受けられる。
(4層500回学習の結果)


 そこで最近13回のAI予想確率と実際に当たった数字の関係を調べた。
 43個の数字各々の予想確率で平均値(16.3)より大きいものと小さい物の数をカウントした(優勢の物に色を付けている)。また実際に選ばれた数字が予想確率分布の上下どちらに属するか当選数字分布を調べた。
 本来AI予想が当たっている場合、当選数字は全て予想確率の高いものの中から選ばれ、当選数字分布は(0,7)となる筈である。しかしこの表ではそうなっておらず、逆に予想確率の低い番号だけで構成されている場合もある事を示している。情報理論によると良く当たる天気予報と同様によく外す天気予報も同じくらい情報を持っている。当たらない事が分かっていればいわゆる逆張りをすればよい。
 そこで再度この表を見ると、当選数字は予想確率分布の数の多い方に偏っている場合が多いことに気づく(そうでない場合を灰色にした)。表で示した13回のうち9回がこれに当たる。 そういう意味ではこのAI予想はある程度の情報を与えていることになる。要するに予想確率分布の数の多い方に限定して張れば良い。そうすると選ぶべき数字が43の1/2~2/3程度に限定され当選確率が上がる事になる。
 
 この数をもっと限定できる適切な Deep Learning のパラメータがあるのかどうか、あれこれ探ってみたいが時間がかかりすぎるのが欠点。

・・・つづく・・・