自力でLチカ8〜サイコロプログラムの説明〜
2024年7月19日(金)は、5割ほどの出席率でした。サイコロプログラムは、今回で最後です。コードの詳しい意味について、解説しました。まだできていないメンバーは、完成に向けてラストスパートです。
- 18時00分~18時20分 タイピング練習
- 18時20分~18時35分 マウス練習
- 18時35分~19時50分 サイコロプログラム
- 19時50分~20時00分 あとかたづけ
Contents
タイピング練習とマウス練習
タイピングの練習は、「寿司打」、マウスの練習は「ソリティア」です。
- 寿司打
https://sushida.net - ソリティア(クロンダイク)
https://playingcards.jp/solitaire/klondike/
どうもソリティアはパズル要素が強すぎて、そちらに気を取られるメンバーが多いよう。無心でマウス操作に没頭できるゲームがあるといいなあと思います。ないなら作ろうというのが我々の発想ですが……。
LED7つを使ったサイコロプログラムを理解しよう
サイコロを表示するプログラムの改良も、前回までで完成しました。細かい注文をつければまだ作り込みたいところはありますが、本来機能は実現したので一旦完成とします。
このプログラムには、さまざまなテクニックが散りばめられています。そのあたりを中心に説明しました。
LEDの点灯消灯を0と1の2次元リストで表現すること
コードの書き方云々はおいおいでいいとして、大切なのは動作をコードどのように表現するかということです。たとえば、下のコードはLEDが点灯するか消灯するかを0と1に対応させて定義したものです。
#1~6の数字に対応した目を配列で指定する
POINT_NUM =[[0, 0, 0, 1, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 1, 0, 0, 1],
[1, 1, 0, 0, 0, 1, 1],
[1, 1, 0, 1, 0, 1, 1],
[1, 1, 1, 0, 1, 1, 1]]
led.value(1)とすれば点灯し、led.value(0)とすれば消灯するプログラムは以前に書いたことがあります。しかし、LED一つ一つを書いていては大変です。そこで人間にとって意味のあるかたまりでまとめて、上のコードのように2次元リストにすることはよくあります。
初期化(イニシャライズ)しよう
コードでいうと、LEDを表示するところで使われています。
#サイコロの目をLEDで表示する関数
def blinkDice(num, pattern):
for i in range(7):
leds[i].value(0)
for i in range(7):
leds[i].value(pattern[num-1][i])
このコードは一度すべてのLEDを消灯してから、指定するLEDを点灯するプログラムです。
この場合、一度すべてのLEDを消灯する処理を「初期化」といいます。なぜ初期化をするかというと、以前のLEDの状態がどのような状態でも期待した動作を保証するためです。
かんたんに絵を描く時を例にします。絵を描く時に、画用紙にすでになにか描かれていたら、その上から絵を描いても自分が描きたい絵にならないかもしれません。そこで、白紙状態から描き始めるはずです。プログラムでは、白紙にする処理が初期化です。
マイコンで割り込みは良いこと
割り込みについて説明すると、メンバーから「やっちゃだめ」とさんざん言われました。行列の割り込みはだめですが、マイコンプログラムの割り込みはOKです。
プログラムで割り込みの部分はこちらです。
def startDice(p):
for _ in range(20):
randomDice()
dice()
start_btn.irq(trigger = Pin.IRQ_FALLING, handler=startDice)
割り込みはピンの状態やタイマーを監視していて、条件が整ったら決められた動作を行う処理です。
これくらいの処理なら割り込みで書く必要はないかもしれません。しかし、並列でたくさんの処理を走らせているときには割り込みを知らないとコードがいたずらに複雑になります。
以上のように、コードをの書き方を覚えるよりも、「なぜそのようなコードを書くのかを理解する」のが大変重要です。
質問がありました
説明をしているときに、いくつか質問がありました。
2進数とはなにか?
小学生のメンバーからの質問は、「2進数とはなにか?」という質問でした。
プログラムでは当たり前のように出てくる2進数です。学校で習うのは、高校1年生だそうです。詳しい説明は下のサイトがわかりやすいので、車輪の再発明は避けます。2進数(二進法)以外の説明もありますが、そこは無視して読めば、絵も多いので理解しやすいと思います。
知識としての2進数はこれで十分です。大切なのは、「コンピューターではなぜ2進数を使うのか」ということです。コンピューターは電気で動きます。つまり、電気があるか・ないかしか判断できません。「電気があるを1、電気がないを0」(もしくはその逆)に割り当てることで、高速に計算することを実現しています。
さきに書いた、LEDが点灯するときは1、消灯するときは0というのも2進数の考え方にもとづいて設定しています。このように、プログラムを書くときは2進数をつかって考えるということを覚えておきましょう。
プルアップをしないとどうなるか?
もう一つの質問は、プルアップをしないとどうなるかという質問です。実は割り込みの設定のところで、先にスイッチに対してPULL_UPを設定しています。これがなかったらどうなるか?とうい質問です。
#サイコロスタートスイッチ
start_btn = Pin(12, Pin.IN, Pin.PULL_UP)
答えは、おそらく「動作が不安定になる」です。動作が不安定になるとは、「ボタンを押してもスタートしたり、しなかったりする」ということです。いうなれば、プルアップは初期化です。
これもマイコンプログラミングでよく出てくるテクニックです。
さて、次回、スペシャルな先生をお呼びして、スペシャルな課題に取り組みます。それが終わったら、8月第2週からモーター制御をやってみようと計画しています。