パーソナルブログメモリ

a = [1, 1]
for _ in "*" * 999: a += [sum(a[-2:])]
print(a)

OSを作っている(のだろうか?)

2018-11-18 | DMB-8836(自作ゲーム機)
Lチカから初めて9日目
昨日完成したゲーム機 DMB-8844(自称)で簡単なゲーム作ってみようとします。

ところが、その前にOSを作らないといけない羽目に

monitorに見立てたDOTMATRIXと電子ブザー4つをスレッドで動かすことに
python3のスレッドもはじめて使って苦労してます。

いろいろ詰め込んだせいかボタン押してのスクロールにもっさり感があります。
あと電源が足りないのか電子ブザーの音量がまちまち。(接触不良かも)

<説明>という名の備忘録
RPi.GPIO(ドットマトリクス、ボタンに利用)とpigpio(電子ブザーに利用) 2つのライブラリを利用しています。
pigpioを使っているのでsudo pigpiod(pigpio利用のデーモン)でデーモンの起動が必要。

ドットマトリックス表示はvram(32x24) vx,vyの位置から8x8表示 1ドットは明度0-9
サウンドは27.5Hz(88鍵盤の左端)から半音ずつ120の音階を4チャンネル。
ボタンは4つ

ゲーム用の命令4つ
dprint(x,y,n) vramの(x,y)の位置に明度nを設定
dbox(x,y,w,h,n) dprintを幅w高さhの範囲で設定
button() 現在押されているボタンを返す。左から"L" "U" "D" "R"の文字列を連結
play(n,arr) チャンネルnに音階数の配列arrを渡すと配列順に音階を鳴らす

このプログラムの説明
起動させると起動音を4チャンネルで
boxをvramの端に3つ表示
buttonで上下左右にvramを起動、さらに各チャンネルの音を鳴らす
button4つの全押しでGPIOを開放して終了

import time
import RPi.GPIO as GPIO
import  threading
import copy
import pigpio as PIGP

#RPiGPIO init
GPIO.setmode(GPIO.BCM)

#pigpio buzzer init
pigp = PIGP.pi()
soundpin = [12,13,18,19]
for p in soundpin:
  pigp.set_mode(p, PIGP.OUTPUT)
  pigp.hardware_PWM(p, 0, 0)

#buzzer
sstop=[0,0,0,0]
snum=0
sarr=[]

#onkai
hz=[0]
for i in range(120):
  hz+=[int(27.5*(1.05946364**i))]

#start sound
try:
  for j in range(1):
    for i in range(400,1000,10):
      for p in soundpin:
        pigp.hardware_PWM(p, i, 200000)
      time.sleep(0.01)
  for i in range(120):
    for p in soundpin:
      pigp.hardware_PWM(p, hz[i] ,500000)
    time.sleep(0.01)
except KeyboardInterrupt:
    pass

#moniter
vx=0
vy=0
vw=32
vh=24
vstop=0#1 thread stop
vram=[[0 for i in range(vw)] for j in range(vh)]

#dotmatrix GPIO pin
high=[2,3,4,17,27,22,10,9]
low=[24,25,8,7,15,16,20,21]

#button GPIO pin
for pin in [11,5,6,26]:
    GPIO.setup(pin,GPIO.IN,pull_up_down=GPIO.PUD_UP)

#dotmatrix GPIO pin
for pin in [2,3,4,17,27,22,10,9,24,25,8,7,15,16,20,21]:
   GPIO.setup(pin, GPIO.OUT) 

#### graphic ####
def dbox(x,y,w,h,n):
    for lx in range(x,x+w):
        for ly in range(y,y+h):
            dprint(lx,ly,n)
          
def dprint(x,y,n):
    global vram,vw,vh
    if 0>x or 0>y or x>vw-1 or y>vh-1:return
    vram[y][x]=n

def monitor():
    global vram,vx,vy,vstop,high,low
    while True:
        for t in [0,4,8,1,3,5,7,9,2,6]:
             for y in range(8):
                for x in range(8):
                    if vstop==1:return
                    if vram[y+vy][x+vx]>t:
                        pinSet(high[x], 1)
                    else:
                        pinSet(high[x], 0)
                pinSet(low[y], 0)
                time.sleep(0.00001)
                pinSet(low[y], 1)

def pinSet(pin_num,sw):
    if pin_num in [2,3,4,17,27,22,10,9,24,25,8,7,15,16,20,21]:
        if sw==0:
            GPIO.output(pin_num, GPIO.LOW)
        else:
            GPIO.output(pin_num, GPIO.HIGH)

#### sound ####
def play(num,arr):
    global snum,sarr,sstop
    snum=num
    sarr=copy.deepcopy(arr)
    sstop[num]=1
    time.sleep(0.3)
    sstop[num]=0
    thread = threading.Thread(target=playsub)
    thread.start()

def  playsub():
    global snum,sarr,sstop,soundpin
    n=snum
    arr=copy.deepcopy(sarr)
    for  i in arr:
        if sstop[n]==1:
            pigp.hardware_PWM(soundpin[n], 0 ,0)
            break
        pigp.hardware_PWM(soundpin[n], hz[i] ,500000)
        time.sleep(0.2)
    pigp.hardware_PWM(soundpin[n], 0 ,0)

#### button ####
def button():
    r=""
    for b,p in zip("LUDR",[11,5,6,26]):
        if GPIO.input(p)==0:r+=b
    return r

#monitor start
thread_1 = threading.Thread(target=monitor)
thread_1.start()

dbox(0,0,8,8,1)
dbox(2,2,4,4,6)
dbox(8,8,6,6,9)

while True:
    if "L" in button():
        if vx>0:vx=vx-1
        play(2,[j for j in range(30,50)])
    if "U" in button():
        if vy>0:vy=vy-1
        play(0,[j for j in range(40,60)])
    if "D" in button():
        if vh-9>vy:vy=vy+1
        play(1,[j for j in range(50,70)])
    if "R" in button():
        if vw-9>vx:vx=vx+1
        play(3,[j for j in range(40,60)])
    if button()=="LUDR":
        vstop=1
        time.sleep(0.01)
        break
    time.sleep(0.001)

#end clear
GPIO.cleanup()
sstop=[1,1,1,1]
time.sleep(0.3)
for p in soundpin:
  pigp.hardware_PWM(p, 0, 0)
  pigp.set_mode(p, PIGP.INPUT)
pigp.stop()

最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。