たまにある祝日はサービスデー

2024年2月23日(金)は、祝日でした。たまに金曜日が祝日のときで、わたしの都合がつけば13時からクラブを開始することがあります。13時から20時までの間で、メンバーの好きな時間帯に来てもらったら良いという仕組みで運営しています。帰るのもメンバーの都合で決めてもらったら良いのです。

そして、この日はわたしが全員に同じテーマでさせることはありません。メンバーがそれぞれ課題を持って集います。クラブを開けている時間が長くて、メンバーが来るのが分散するので、わたしが一人あたりに向き合える時間が長くなります。普段はわたしが見きれていないところも、時間をかけて見ることができます。実は大サービスデー、チャンスです。

大学共通テスト「情報」の模擬言語

あるメンバーが持ってきた課題は、大学共通テストの「情報」科目の問題です。あらたに設定された「情報」には、「模擬言語」が出題されます。

模擬言語以外の問題は、情報リテラシーや数学の問題なので、専門的に学習しなくても点がとれます。しかし、模擬言語はプログラムを専門的に学習していないと、解くのに苦労する問題です。

模擬言語と言っても、Pythonによく似た言語です。しかも、モダンでパイソニックな記述方法ではありません。わたしが学生のときに学んだときの気持ちを思い出しながら、一緒に取り組んだのでした。

超音波測距センサー(HC-SR04)とサーボモーター(SG90)を連携させる

前回お休みのメンバーは、超音波距離センサーのプログラムをしたいということでした。

コードを書いてから、配線をします。わたしとマンツーマンで取り組むと、30分もあれば完成します。できあがったら、サーボモーターと組み合わせて動かしてみます。下の動画のように、HC-SR04で測定した距離とSG90の回転角が連動するようにプログラムします。

コード自体は、これまでのクラブ活動で書いたものを組み合わせて、改造します。すこしだけ追加でコードを書きます。

ただ、比例の考え方ができないと、追加でコードを書くことができません。小学校5年生以上の数学で学習する内容です。これをイメージできるように説明するのが難しいのです。

下はわたしが説明のときに書いたホワイトボードの図です。

これでかんたんに理解してくれるメンバーもいれば、そうでないメンバーもいます。手を変え品を変え、いろんな例を出して説明します。これ、なかなかハードなんですよ

さて、コードは下の通り。

from machine import Pin, PWM, time_pulse_us
import utime

#センサー初期設定
TEMP = 20

TRIG_PIN = 14
ECHO_PIN = 15

s_speed = 331.5 + 0.6 * TEMP

trig = Pin(TRIG_PIN, Pin.OUT)
echo = Pin(ECHO_PIN, Pin.IN)

trig.value(0)
utime.sleep(1)

#サーボ初期設定
SERVO_PIN = 16
PWM_FREQ = 50

def measure():
    trig.value(1)
    utime.sleep_us(20)
    trig.value(0)
    
    while echo.value() == 0:
        sigoff = utime.ticks_us()
    while echo.value() == 1:
        sigon = utime.ticks_us()
    dist = (sigon - sigoff) * s_speed / 2 * (10 ** -4)
    return dist

def pulse_width(val, freq = PWM_FREQ, resol = 65535):
    pulse = freq * val * 1e-6 * resol
    return int(pulse)

def rotmotor(pulse):
    duty = pulse_width(pulse)
    servo.duty_u16(duty)
    utime.sleep(0.1)

def cnvPulse(degrees):
    if degrees < -90:
         degrees = -90
    if degrees > 90:
         degrees = 90
    return -degrees*1000/90+1500

def cnvDeg(dist):
    if dist < 5:
        dist = 5
    if dist > 105:
        dist = 105
    deg = 1.8 * dist - 99
    return deg

servo = PWM(Pin(SERVO_PIN))
servo.freq(PWM_FREQ)

while True:
    distance = measure()
    deg = cnvDeg(distance)
    pulse = cnvPulse(deg)
    rotmotor(pulse)

コードのうち、ハイライトで示した行が新しく書いた行です。それ以外は、これまでのクラブ活動で一度書いたコードです。

動画を見て分かる通り、サーボの動きがあまりスムーズではありません。また、測定距離が50cmを超えると、極端に精度が悪くなります。このあたりを解決できるとよいのですが。