2025年11月08日

ラズピコでナイトライダー ナイト2000のスキャナ作り #2

先日から作り始めたラズピコでのナイト2000スキャナ作り、もうちょっと
段階的に進めて行く予定でしたが、何となくそれっぽいものが出来上がって
しまったので、ひとまずの完成という事にしておきます。

RPKittScanner_01.jpg

回路は前回作ったものと変わりません。まぁマイコンを使った電子工作は、
プログラムがメインですからね…。

前回は8個のLEDを往復させる所まで作りました。脳内では可変抵抗を使い
往復速度の可変、電源を入れた時の全点灯、各LEDに残光を付ける、という
形で段取りを考えていたのですが、個別にやっていると訳が分からなくなり
そうな気がしたので、一気にバーっと作ってしまった訳です。

結果、プログラムは下記のようになりました(長いです)。#から始まる行は
コメントアウトです。一応分かる範囲で注釈を入れて置きました(赤字)。

from machine import ADC,Pin,PWM
from time import sleep

led1 = PWM(Pin(0)) #0~7ピンをPWM出力に設定
led2 = PWM(Pin(1))
led3 = PWM(Pin(2))
led4 = PWM(Pin(3))
led5 = PWM(Pin(4))
led6 = PWM(Pin(5))
led7 = PWM(Pin(6))
led8 = PWM(Pin(7))
led1.freq(1000) #各LEDのPWM周波数を1kHzに設定
led2.freq(1000)
led3.freq(1000)
led4.freq(1000)
led5.freq(1000)
led6.freq(1000)
led7.freq(1000)
led8.freq(1000)

Speedpot = ADC(Pin(26)) #26ピンADC0を変数Speedpotに設定


value1 = 65535 #最大輝度(デューディ比100%)
value2 = 20000 #残光高輝度(デューティ比30%)
value3 = 8000 #残光中輝度(デューティ比12%)
value4 = 3000 #残光低輝度(デューティ比4.5%)
value0 = 0 #消灯(デューティ比0%)
LightUp = 0.05 #全点灯 明るくなる間隔
LightDn = 0.2 #全点灯 暗くなる間隔

#Interval = 0.07
#Potvalue = Speedpot.read_u16()
#Interval = (Potvalue / 16384) *0.1
#print(Interval)

#FullyLightup
led1.duty_u16(value4) #電源ON時の全点灯
led2.duty_u16(value4)
led3.duty_u16(value4)
led4.duty_u16(value4)
led5.duty_u16(value4)
led6.duty_u16(value4)
led7.duty_u16(value4)
led8.duty_u16(value4)
sleep(LightUp)
led1.duty_u16(value3)
led2.duty_u16(value3)
led3.duty_u16(value3)
led4.duty_u16(value3)
led5.duty_u16(value3)
led6.duty_u16(value3)
led7.duty_u16(value3)
led8.duty_u16(value3)
sleep(LightUp)
led1.duty_u16(value2)
led2.duty_u16(value2)
led3.duty_u16(value2)
led4.duty_u16(value2)
led5.duty_u16(value2)
led6.duty_u16(value2)
led7.duty_u16(value2)
led8.duty_u16(value2)
sleep(LightUp)
led1.duty_u16(value1)
led2.duty_u16(value1)
led3.duty_u16(value1)
led4.duty_u16(value1)
led5.duty_u16(value1)
led6.duty_u16(value1)
led7.duty_u16(value1)
led8.duty_u16(value1)
sleep(0.3)

led1.duty_u16(value2) #全点灯を消灯する
led2.duty_u16(value2)
led3.duty_u16(value2)
led4.duty_u16(value2)
led5.duty_u16(value2)
led6.duty_u16(value2)
led7.duty_u16(value2)
led8.duty_u16(value2)
sleep(LightDn)
led1.duty_u16(value3)
led2.duty_u16(value3)
led3.duty_u16(value3)
led4.duty_u16(value3)
led5.duty_u16(value3)
led6.duty_u16(value3)
led7.duty_u16(value3)
led8.duty_u16(value3)
sleep(LightDn)
led1.duty_u16(value4)
led2.duty_u16(value4)
led3.duty_u16(value4)
led4.duty_u16(value4)
led5.duty_u16(value4)
led6.duty_u16(value4)
led7.duty_u16(value4)
led8.duty_u16(value4)
sleep(LightDn)
led1.duty_u16(value0)
led2.duty_u16(value0)
led3.duty_u16(value0)
led4.duty_u16(value0)
led5.duty_u16(value0)
led6.duty_u16(value0)
led7.duty_u16(value0)
led8.duty_u16(value0)

sleep(0.2)

while True:

Potvalue = Speedpot.read_u16() #可変抵抗の値を読み取ってPotvalueに入れる
Interval = (Potvalue / 16384) *0.1 # Potvalueの値を16,384で割って×0.1したものをIntervalに入れる

#Outbound #往路点灯
#LED1
led1.duty_u16(value1)
led5.duty_u16(value0)
led4.duty_u16(value4)
led3.duty_u16(value3)
led2.duty_u16(value2)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led1.duty_u16(value0)

#LED2
led2.duty_u16(value1)
led1.duty_u16(value2)
led4.duty_u16(value0)
led3.duty_u16(value4)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led2.duty_u16(value0)

#LED3
led3.duty_u16(value1)
led1.duty_u16(value3)
led2.duty_u16(value2)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led3.duty_u16(value0)

#LED4
led4.duty_u16(value1)
led1.duty_u16(value4)
led2.duty_u16(value3)
led3.duty_u16(value2)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led4.duty_u16(value0)

#LED5
led5.duty_u16(value1)
led1.duty_u16(value0)
led2.duty_u16(value4)
led3.duty_u16(value3)
led4.duty_u16(value2)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led5.duty_u16(value0)

#LED6
led6.duty_u16(value1)
led2.duty_u16(value0)
led3.duty_u16(value4)
led4.duty_u16(value3)
led5.duty_u16(value2)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led6.duty_u16(value0)

#LED7
led7.duty_u16(value1)
led3.duty_u16(value0)
led4.duty_u16(value4)
led5.duty_u16(value3)
led6.duty_u16(value2)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led7.duty_u16(value0)

#LED8
led8.duty_u16(value1)
led4.duty_u16(value0)
led5.duty_u16(value4)
led6.duty_u16(value3)
led7.duty_u16(value2)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led8.duty_u16(value0)

#Return #復路点灯
#LED7
led7.duty_u16(value1)
led5.duty_u16(value0)
led6.duty_u16(value4)
led8.duty_u16(value2)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led7.duty_u16(value0)

#LED6
led6.duty_u16(value1)
led7.duty_u16(value2)
led8.duty_u16(value3)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led6.duty_u16(value0)

#LED5
led5.duty_u16(value1)
led6.duty_u16(value2)
led7.duty_u16(value3)
led8.duty_u16(value4)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led5.duty_u16(value0)

#LED4
led4.duty_u16(value1)
led5.duty_u16(value2)
led6.duty_u16(value3)
led7.duty_u16(value4)
led8.duty_u16(value0)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led4.duty_u16(value0)

#LED3
led3.duty_u16(value1)
led7.duty_u16(value0)
led6.duty_u16(value4)
led5.duty_u16(value3)
led4.duty_u16(value2)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led3.duty_u16(value0)

#LED2
led2.duty_u16(value1)
led6.duty_u16(value0)
led5.duty_u16(value4)
led4.duty_u16(value3)
led3.duty_u16(value2)
sleep(Interval)
Potvalue = Speedpot.read_u16()
Interval = (Potvalue / 16384) *0.1
led2.duty_u16(value0)


本来プログラムというのは個々の命令の機能や使い方をしっかりと把握した
上で、それらを使って組んで行くというのが常套手段なんでしょうが…。
さすがに BASIC しか学んだ事のない自分にとっては超難解なので、様々な
ブログやプログラム例を漁っては部分的に抜き出し、パラメータや用法等を
変えて上手く動くように継ぎ接ぎで作るしかありませんね。

microPython を使いこなしている人から見たら「何これ酷い🤣」と言われ
そうですが、今の自分はこれが限界です😇

while True: 以前が初期設定と電源ON時の挙動、以降が往復ループです。
LEDをひとつ点灯させるごとに毎回可変抵抗の値を読みに行っているのは、
速度変更をなるべくリアルタイムに反映するため。ループの先頭に1個だけ
だと1往復するまで速度が変わらないので、超絶ゆっくりにするとちっとも
速度が反映されずイライラします(笑)。

配列変数の使い方などまるで分からない事だらけなので、本来ならループ等
使って簡潔にまとめられそうな所を、全部バラで書いています。
この辺りはもっと勉強して、使い方を頭に叩き込まなければならないので、
それはおいおいやって行くとします。


このプログラムをラズピコに転送します。

RPKittScanner_02.png

転送時にファイル名を main.py とする事で、PCに接続してThonnyから制御
しなくても勝手にプログラムを読み込み実行してくれるので、電源さえ供給
してやればスタンドアロンで動きます。




動画にしてみました(31秒 音声なし)。

電源ON→全点灯→往復動作で速度可変、となっています。

ラズピコは一応CPUがデュアルコア 133MHzで動いているので、こんなにも
雑で力業なプログラムでも重くならず動いてくれますが、本当は残光の表現
を6段階にしたかった…(現状は4段階)。

でも、ただでさえゴチャゴチャしているのに、この上さらに残光を増やすと
手に負えなくなりそうな気がしたので、とりあえずの4段階。
自分としては、ICで作った回路のように電解コンで残光を表現した方が自然
というか、電球らしさが出ていて好みなのですが。


今後プログラム技術が身に付いたら、もっと単純化する予定~。



posted by ゆう at 2025年11月08日| Comment(0) | ラズピコ | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
コチラをクリックしてください
最近の記事