電子楽器を作りたい話④ アンプ

 今回はアンプです。今回でひと段落し、しばらくはいろいろ試行錯誤することになると思います。

・アンプとは
 電子楽器やエフェクターから出力される信号は数mV~数十mVと非常に小さく、これをスピーカーやヘッドフォンに入れても音はなりません。それなので、信号を増幅し、数V程の音が鳴る大きさの信号に変換するのがアンプの役目です。ものによってはイコライザーのような機能が付いたものもあるらしいのですが、今回は単純に増幅するだけのものになります。

・回路
amp_回路図
 今回は難しいことを考えずに反転増幅回路を使いました。非反転増幅回路でもいいのですが、増幅率の計算が簡単なのと、こちらのほうがメジャーなので反転増幅回路にしました。
 増幅率は、
Vout/Vin=R1/R2
となります。この回路では10倍となっています。

 今回アンプで増幅しました。これのおかげで前回のように音を鳴らすことが可能になりました。
 また、改良ができたら記事を書こうと思います。それではまた今度。

電子楽器を作りたい話③ オーバードライブ

 やっと最初の波ができたのでこれを加工していきます。まあ、正弦波でもいいのですが、なんか味気ない気がするので加工することにします。波を変形させるものと言ったらエレキギターのエフェクターということで、その中でも代表的な? オーバードライブを作りました。

・オーバードライブとは
 オーバードライブがどういうものかはよくわかりません。自分はバンドをやってたわけでも、バンドの音楽をよく聞いてるわけでもないので当たり前です。ギュイーンってする奴だということは、隣でギターを弾いている弟から教わりました。
 弟全面協力のもと、ギターの出力波形とオーバードライブを通した後の波形をオシロスコープではからせてもらいました。
IMG_1226IMG_1225

 上がギターの波形、下がオーバードライブを通した後の波形です。
 全体的に増幅されていて、一定以上の部分を平滑してる感じかなと思います。

・回路図
 ググりました。色々出てきたので一番詳しく乗っていたFULL TONE OCDにしました。

overdrive_回路図
 GNDは全て仮想のものです。C9はタンタルコンデンサのほうが良いらしいのですが、電解コンデンサでもよいらしかったので電解コンデンサにしました。
 回路図には書き忘れましたが、10kΩ抵抗と500kΩ抵抗がBカーブ、1MΩ抵抗がAカーブとするのがよいそうです。

・出力

 まだアンプで増幅していませんが、出力波形としてはこんな感じです。 また、ギターで使ってみたらこのような感じでした。
 ノイズが思ったより大きいのでバイパスコンデンサを入れたのですが、弟にノイズが大きいほうがいいといわれて外されました。


 今回はオーバードライブを作りました。買うと2万円以上するものなのですが、自分で作れば5000円前後で作ることができました。
 今回はここまでです。次回はチラチラ出てきたアンプを作ります。それではまた今度。

電子楽器を作りたい話② ウィーンブリッジ

 前回、「次回はオーバードライブをする」とか言ってましたが、よく考えたらまだ最初の入力波ができてませんでした。なので今回は正弦波発生回路であるウィーンブリッジです。

・ウィーンブリッジ
 比較的簡単に正弦波が出せる回路で、抵抗ちょっととコンデンサ少しとオペアンプ一つでできます。
 今回は、周波数が簡単に変えられることからこの回路を採用しました。

・回路
ウィーンブリッジ_回路図
発振条件
1+R3/R4+C2/C1=(R1+R2)/R2

発振周波数
f=1/(2π√C1C2R3R4)

 この式の通り、発振条件よりR1=R2*2にしておくとC1=C2,R3=R4で正弦波が出力され、またそれらの値の掛け算で周波数が決定します。R3とR4の値が等しくないといけないので、二連ボリュームがあると便利だと思います。

・出力
Du0uRDGUUAAoGXH
 出力はこんな感じです。適当に選んだ抵抗とコンデンサでほとんどひずみのない正弦波が出ました。

 周波数を変えるために二連ボリュームが欲しいのですが、構想している楽器の形状に合わせるとサイズが大きくなってしまい、なかなか見つかりません。
 今回はここまでです。次回は今度こそオーバードライブをやります。それではまた今度。

電子楽器を作りたい話① 仮想GND

 ちょっと前から自分で電子楽器を作りたく思っていて、ちょうどやることがなくなったので基礎的なことから始めてみました。いっぺんに全部やるわけにもいかないので今回は仮想GNDです。

・仮想GNDとは
 オペアンプを使った回路を作成するとき、通常は電源を二つ用意し、マイナスの電位を作らなければなりません。しかし、電源を二つ用意するはめんどくさいので一つの電源で疑似的にマイナスの電位を作ってしまおうというのが仮想GNDです。

・回路
virtual gnd_回路図

 回路としてはこんな感じです。これにトランジスタとか?オペアンプとか?を追加するともっと安定するらしいのですが、まあこれでも十分安定していたと思います。抵抗を大きくすると大きな電流が取り出せるようになりますが、安定性が下がるといったような特徴があります。
 実際に使うときは、Vccを正電源にGNDを負電源につなぎ、GNDを本来はつなぐはずだったところに仮想GNDをつなぎます。

 今回はここまで、次はすぐ出します。次回はオーバードライブの予定です。それではまた今度。

4*4*4 LED CUBEを作った話

今回は4*4*4のLEDキューブを作りました。

・回路
LEDCUBE_回路図
 今回使用した回路はこのようなものです。

 LEDCUBE LO
 論理回路にするとこんな感じです。

 軽く調べたところシフトレジスタを使って作っているものが多かったのですが、シフトレジスタが家になかったのと、プログラムを直感的に描くために今回は使いませんでした。(みんながやってることをやってもつまらないしね)
 ANDが家になかったのでNORで代用しています。
 見ての通り、X,Y,Z座標を決めてあげるとそこのLEDが光るという単純なもので、直感的にプログラムを書くことができるようにしました。

・必要なもの
NORかAND*4
LED*64
トランジスタ*4
Arduino UNO
ジャンパ線たくさん
導線たくさん
ピンソケットかピンヘッダそこそこ
ユニバーサル基板の切れ端

・作り方
 適当に作ります。写真を適当にとったらピンボケがひどかったです。
①まず大量の銅線を切り、両端をペンチで挟みねじりながら引き伸ばします。
 今回は、100mm*32(Z座標決定用の格子用),160mm*20(XY座標用16+Z座標の格子への導線の集積用)を使いました。
UTFZ4192

②格子を作る
 今回は、方眼紙の上に並べて、それをはんだ付けしました。
RQNK3542

③LEDをつける
 気合で付けます。練り消しとか粘土とかでLEDを固定するとやりやすい気がします。
WJLE7718


④LEDをつけた格子同士をつなげる
 今回は、洗濯ばさみで立たせてやりました。
SBFK4744

⑤基板でコネクタを作れば完成
MBUU0145



・動作
 実際に光るとこんな感じです。そこそこきれいにできたと思います。プログラムをいじればもっといろいろな光り方ができると思いますが、満足しちゃったのでここまでで。(こんな単純なパターンでも全部で2000行近くなってしまったし...)


・総括
 はんだ付けの練習としてはかなり良かったです。また、行き当たりばったりで作っていたので無茶なところにはんだごてをねじ込むことになりましたが、完成したのでオッケーです。
 今度は電子楽器? を作ろうと思ってますが、全然仕組みが決まってません。年末で秋月が閉まる前までには部品を買っておきたいです。それではまた今度。

Arduinoで静電容量式のセンサーを作った話。

 Arduino日本語リファレンスを見てたら面白いものがあったので使ってみました。

 CapSenseというもので、適当な抵抗一本とアルミホイルなどで作ることができます。

 このファイルをダウンロードし、IEDのスケッチ→ライブラリのインクルード→.zip形式のライブラリをインストールと進みライブラリを使えるようにします。

 あとは、リファレンスに書いてあるサンプルプログラムを入れ実行すると、センサーの値が返ってきます。

静電
 これは、読み取りを一つにしたものです。
 使う抵抗によってセンサーの値が全然違うものになってくるのですが、こんかいは1MΩ抵抗を使っています。
 何も上にない時が一桁台、5cm離れたところあたりに手をかざしたときに30程になり、マスキングテープを挟んで触れているときは700台後半と変化したので、実用に足る精度ではないでしょうか?

 今回静電容量センサーを作りましたが使う予定はありません。
 最近LEDCubeを作っているので、近々ブログにかけると思います。それではまた今度。

Pygameでゲームを作ってみた話

 今回は、Pygameでパックマン風のゲームを作りました。サークルでEne-1の計器を作っているときにPygameを使っていて、それの続きとして作ってみました。

素材
 使いたい人がもし仮にいたら勝手に使ってください。
・chip2
chip2
・coin
coin
・enemy-2
enemy-2
・message
message
・bon
bom
・step
step

・sozai-1
これだけは、自分では描けなかったので、(●MACK●http://homepage3.nifty.com/looseleaf/)様の素材を使っています。
sozai-1


プログラム
 今回はきれいなプログラムを書く気が起きなかったのと、書いてるうちにどこがどう動いているのかよくわからなくなってきたので、プログラムが雑です。
import pygame,sys
import random


pygame.init()
window_size = (640, 640)
bg_color = (0, 0, 255)
clock = pygame.time.Clock()
screen = pygame.display.set_mode(window_size)
pygame.display.set_caption("GAME")

img_bg = pygame.image.load('chip2.png')
message = pygame.image.load('message.png')
charae = pygame.image.load('enemy-2.png')
chara = pygame.image.load('sozai-1.png')
bom = pygame.image.load('bom.png')
coin = pygame.image.load('coin.png')
step = pygame.image.load('step.png')
num_chips_per_line = int(img_bg.get_width() / 32)

map_data = [
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
]
i=0
chara_ex = [9,10,11,12]
chara_ey = [9,10,11,12]
chara_exa = [9,10,11,12]
chara_eya = [9,10,11,12]
coin_x = [1,1,1,1]
coin_y = [1,1,1,1]
coin_s = [0,0,0,0]
chara_x = 1
chara_y = 1
chara_xa = 1
chara_ya = 1
chara_xb = 1
chara_yb = 1
way_ex = [1,1,1,1]
way_ey = [1,1,1,1]
flame = 0
dir = "S"
dir_e = [3,3,3,3]
flag = 0
flag_1 = 0
flag_2 = 0
flag_3 = 0
walk = 0
deth = 0
c = 0
do = 0
bom_x = 0
bpm_y = 0
j = 0

#coin
for i in range(0,4):
while True:
coin_x[i] = random.randint(0, 19)
coin_y[i] = random.randint(0, 19)
if (map_data[coin_y[i] * 20 + coin_x[i]] == 0):
break

#step
while True:
step_x = random.randint(0, 19)
step_y = random.randint(0, 19)
if (map_data[step_y * 20 + step_x] == 0):
break

end_game = False
while not end_game:
for event in pygame.event.get():
if event.type == pygame.QUIT:
end_game = True
#map
for y in range(0, 20):
for x in range(0, 20):
i = y * 20 + x
pos_x = x * 32
pos_y = y * 32
c = map_data[i]
dx = c % num_chips_per_line
dy = int(c / num_chips_per_line)
screen.blit(img_bg, (pos_x, pos_y), (32 * dx, 32* dy, 32,32))

#end event
for i in range(0,4):
if(chara_ex[i] == chara_x and chara_ey[i] == chara_y):
flag = 1

if(flag == 0 or flag == 2):

#my character
if (flame % 30 == 0):
pressed = pygame.key.get_pressed()
if pressed[pygame.K_UP]:
chara_y = max(chara_y - 1, 0)
if pressed[pygame.K_LEFT]:
chara_x = max(chara_x - 1, 0)
if pressed[pygame.K_DOWN]:
chara_y = min(chara_y + 1, 20 - 1)
if pressed[pygame.K_RIGHT]:
chara_x = min(chara_x + 1, 20 - 1)
walk = 1
if (chara_y == chara_yb and chara_x == chara_xb):
walk = 0

chara_xa = chara_x
chara_ya = chara_y

if (map_data[chara_y * 20 + chara_xb] == 1):
flag_1 = 1
if (map_data[chara_yb * 20 + chara_x] == 1):
flag_2 = 1
if (map_data[chara_y * 20 + chara_x] == 1):
flag_3 = 1

if (flag_3 == 1):
chara_x = chara_xb
chara_y = chara_yb
if (flag_1 == 0 and flag_2 == 1):
chara_y = chara_ya
elif (flag_1 == 1 and flag_2 == 0):
chara_x = chara_xa

if (chara_x > chara_xb):
dir = "E"
if (chara_x < chara_xb):
dir = "W"
if (chara_y > chara_yb):
dir = "S"
if (chara_y < chara_yb):
dir = "N"

#enemy
for i in range(0,4):

if (chara_exa[i] == chara_ex[i] and chara_eya[i] == chara_ey[i]):
while True:
chara_exa[i] = random.randint(0, 19)
chara_eya[i] = random.randint(0, 19)
if (map_data[chara_eya[i] * 20 + chara_exa[i]] == 0):
if (chara_ey[i] > chara_eya[i]):
way_ey[i] = 1
if (chara_ey[i] < chara_eya[i]):
way_ey[i] = 0
if (chara_ex[i] > chara_exa[i]):
way_ex[i] = 1
if (chara_ex[i] < chara_exa[i]):
way_ex[i] = 0
break
#event
if (dir_e[i] == 1):
if (chara_y - chara_ey[i] < 6 and chara_y > chara_ey[i]):
chara_exa[i] = chara_x
chara_eya[i] = chara_y
do = 1
if (chara_x - chara_ex[i] < 6 and chara_x > chara_ex[i]):
chara_exa[i] = chara_x
chara_eya[i] = chara_y
do = 1
if (chara_ex[i] - chara_x < 6 and chara_ex[i] > chara_x):
chara_exa[i] = chara_x
chara_eya[i] = chara_y
do = 1
if (dir_e[i] == 2):
if (chara_x - chara_ex[i] < 6 and chara_x > chara_ex[i]):
chara_exa[i] = chara_x
chara_eya[i] = chara_y
do = 1
if (chara_ey[i] - chara_y < 6 and chara_ey[i] > chara_y):
chara_exa[i] = chara_x
chara_eya[i] = chara_y
do = 1
if (chara_y - chara_ey[i] < 6 and chara_y > chara_ey[i]):
chara_exa[i] = chara_x
chara_eya[i] = chara_y
do = 1
if (dir_e[i] == 3):
if (chara_ey[i] - chara_y < 6 and chara_ey[i] > chara_y):
chara_exa[i] = chara_x
chara_eya[i] = chara_y
do = 1
if (chara_x - chara_ex[i] < 6 and chara_x > chara_ex[i]):
chara_exa[i] = chara_x
chara_eya[i] = chara_y
do = 1
if (chara_ex[i] - chara_x < 6 and chara_ex[i] > chara_x):
chara_exa[i] = chara_x
chara_eya[i] = chara_y
do = 1
if (dir_e[i] == 4):
if (chara_ex[i] - chara_x < 6 and chara_ex[i] > chara_x):
chara_exa[i] = chara_x
chara_eya[i] = chara_y
do = 1
if (chara_ey[i] - chara_y < 6 and chara_ey[i] > chara_y):
chara_exa[i] = chara_x
chara_eya[i] = chara_y
do = 1
if (chara_y - chara_ey[i] < 6 and chara_y > chara_ey[i]):
chara_exa[i] = chara_x
chara_eya[i] = chara_y
do = 1

if (do == 1):
if (chara_ey[i] > chara_eya[i]):
way_ey[i] = 1
if (chara_ey[i] < chara_eya[i]):
way_ey[i] = 0
if (chara_ex[i] > chara_exa[i]):
way_ex[i] = 1
if (chara_ex[i] < chara_exa[i]):
way_ex[i] = 0

if (flame % 30 == 0):
if (dir_e[i] % 2 == 1):
if (map_data[chara_ey[i] * 20 + chara_ex[i] + 1] == 0 and way_ex[i] == 0):
dir_e[i] = 2
if (chara_ey[i] >= chara_eya[i]):
way_ey[i] = 1
if (chara_ey[i] < chara_eya[i]):
way_ey[i] = 0
if (map_data[chara_ey[i] * 20 + chara_ex[i] - 1] == 0 and way_ex[i] == 1):
dir_e[i] = 4
if (chara_ey[i] >= chara_eya[i]):
way_ey[i] = 1
if (chara_ey[i] < chara_eya[i]):
way_ey[i] = 0
elif (dir_e[i] % 2 == 0):
if (map_data[chara_ey[i] * 20 + chara_ex[i] + 20] == 0 and way_ey[i] == 0):
dir_e[i] = 3
if (chara_ex[i] >= chara_exa[i]):
way_ex[i] = 1
if (chara_ex[i] < chara_exa[i]):
way_ex[i] = 0
if (map_data[chara_ey[i] * 20 + chara_ex[i] - 20] == 0 and way_ey[i] == 1):
dir_e[i] = 1
if (chara_ex[i] >= chara_exa[i]):
way_ex[i] = 1
if (chara_ex[i] < chara_exa[i]):
way_ex[i] = 0

if (flame % 30 == 0):
if (dir_e[i] == 1):
chara_ey[i] = chara_ey[i] - 1
elif (dir_e[i] == 2):
chara_ex[i] = chara_ex[i] + 1
elif (dir_e[i] == 3):
chara_ey[i] = chara_ey[i] + 1
elif (dir_e[i] == 4):
chara_ex[i] = chara_ex[i] - 1

flag_1 = 0
flag_2 = 0
flag_3 = 0
do = 0

# coin event
for i in range(0, 4):
if (coin_x[i] == chara_x and coin_y[i] == chara_y):
coin_s[i] = 1

if (coin_s[0] == 1 and coin_s[1] == 1 and coin_s[2] == 1 and coin_s[3] == 1):
flag = 2


#grafic
if(chara_x == step_x and chara_y == step_y and flag == 2):
flag = 4

for i in range(0,4):
if (coin_s[i] == 0):
screen.blit(coin, (coin_x[i] * 32,coin_y[i] * 32), (0, 0, 32, 32))

for i in range(0,4):
if (coin_s[i] == 0):
screen.blit(coin, (i * 32,0), (32, 0, 32, 32))
else:
screen.blit(coin, (i * 32,0), (0,0,32,32))

for i in range(0,4):
if (dir_e[i] == 1):
screen.blit(charae, (chara_ex[i] * 32, chara_ey[i] * 32), (64, 0, 32, 32))
elif (dir_e[i] == 2):
screen.blit(charae, (chara_ex[i] * 32, chara_ey[i] * 32), (32, 0, 32, 32))
elif (dir_e[i] == 3):
screen.blit(charae, (chara_ex[i] * 32, chara_ey[i] * 32), (96, 0, 32, 32))
elif (dir_e[i] == 4):
screen.blit(charae, (chara_ex[i] * 32, chara_ey[i] * 32), (0, 0, 32, 32))

if (flag == 2):
screen.blit(step, (step_x * 32, step_y * 32), (0, 0, 32, 32))

if (dir == "S"):
if (walk == 0):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (32, 0, 32, 64))
elif (flame % 120 > 89):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (32, 0, 32, 64))
elif (flame % 120 > 59):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (0, 0, 32, 64))
elif (flame % 120 > 29):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (32, 0, 32, 64))
elif (flame % 120 < 30):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (64, 0, 32, 64))
elif (dir == "E"):
if (walk == 0):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (32, 128, 32, 64))
elif (flame % 120 > 89):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (32, 128, 32, 64))
elif (flame % 120 > 59):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (0, 128, 32, 64))
elif (flame % 120 > 29):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (32, 128, 32, 64))
elif (flame % 120 < 30):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (64, 128, 32, 64))
elif (dir == "N"):
if (walk == 0):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (32, 192, 32, 64))
elif (flame % 120 > 89):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (32, 192, 32, 64))
elif (flame % 120 > 59):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (0, 192, 32, 64))
elif (flame % 120 > 29):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (32, 192, 32, 64))
elif (flame % 120 < 30):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (64, 192, 32, 64))
elif (dir == "W"):
if (walk == 0):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (32, 64, 32, 64))
elif (flame % 120 > 89):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (32, 64, 32, 64))
elif (flame % 120 > 59):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (0, 64, 32, 64))
elif (flame % 120 > 29):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (32, 64, 32, 64))
elif (flame % 120 < 30):
screen.blit(chara, (chara_x * 32, chara_y * 32 - 32), (64, 64, 32, 64))

elif(flag == 1):
if(j<10):
screen.blit(bom, (chara_x * 32, chara_y * 32), (0, 0, 32, 32))
elif(j<20):
screen.blit(bom, (chara_x * 32, chara_y * 32), (32 * 1, 0, 32, 32))
elif(j<30):
screen.blit(bom, (chara_x * 32, chara_y * 32), (32 * 2, 0, 32, 32))
elif(j<40):
screen.blit(bom, (chara_x * 32, chara_y * 32), (32 * 3, 0, 32, 32))
elif(j<50):
screen.blit(bom, (chara_x * 32, chara_y * 32), (32 * 4, 0, 32, 32))
elif(j<60):
screen.blit(bom, (chara_x * 32, chara_y * 32), (32 * 5, 0, 32, 32))
elif(j>119):
end_game = True
j = j + 1

if(flag == 4):
if(j < 120):
screen.blit(message, (120,240), (0, 0, 400, 64))
else:
end_game = True
j = j + 1

#for i in range(0,4):
# screen.blit(charae, (chara_exa[i] * 32,chara_eya[i] * 32), (128,0,32,32))
pygame.display.flip()
clock.tick(60)
flame = flame + 1
chara_xb = chara_x
chara_yb = chara_y

 かなり適当に作ったので、雑なところが多々ありますが、きちんと動き、それなりに面白かったので満足しています。

 なんかすごくlivedoorの編集ページが重くなってきたのでこれくらいにしておきます。
 それではまた今度。

Ene1-GPに参加した話

 私がReUsというサークルに入ってるという話は何回か出てきたと思いますが、(サークルって言ってるときは大体このサークルです。)そのサークルの主な活動であるEne1-GP MOTEGI KV-BIKEに参加してきました。

 この大会は充電式の単三電池40本で電動バイクを動かして、一周のタイムと60分で走った周回数を競う大会です。

 今回私はエンジニアとして計器のシステムの開発をしました。今回作ったシステムの概要は以下の通りです。
Untitled Diagram
 今回はすべてのセンサーがアナログなので機能のわりに複雑なシステムになりました。

・プログラム
Arduino-slave

#include <Wire.h>
#include <math.h>
int val = 0;
int i = 0;
int stb;
int sta;
int V;
float f;
void setup() {
  Serial.begin(9600);
  Wire.begin(8);
  Wire.onRequest(requestEvent);
  }

void loop() {
  val=analogRead(0);
  Serial.println(val);
  i++;
  if(val > 900){
    sta = 1;
  }else{
    sta = 0;
  }
  if(sta > stb){
      f = 10000 / i;
      V = 55*3.14*f;//なんかいい感じの係数をかける
      Serial.print("V=");
      Serial.println(V);
      i = 0;
  }
  stb = sta;
  delayMicroseconds(100);
}

void requestEvent() {
  Wire.write(V);
}


Arduino-master
#include <SoftwareSerial.h>
#include <math.h>
#include <Wire.h>
 
// rxPin = 2  txPin = 3
SoftwareSerial mySerial(2, 3);
 
// NMEAの緯度経度を「度」(DD)の文字列に変換する
String NMEA2DD(float val) {
  int d = val / 100;
  int m = (((val / 100.0) - d) * 100.0) / 60;
  float s = (((((val / 100.0) - d) * 100.0) - m) * 60) / (60 * 60);
  return String(d + m + s, 6);
}


int val1;//温度
int val2;//電圧
int temp;
float vol;
void setup() {
  Wire.begin();
  mySerial.begin(9600);
  Serial.begin(9600);
  }

void loop() {
  // 1つのセンテンスを読み込む
  String line = mySerial.readStringUntil('\n');
 
  if(line != ""){
    int i, index = 0, len = line.length();
    String str = "";
  
    // StringListの生成(簡易)
    String list[30];
    for (i = 0; i < 30; i++) {
      list[i] = "";
    }
 
    // 「,」を区切り文字として文字列を配列にする
    for (i = 0; i < len; i++) {
      if (line[i] == ',') {
        list[index++] = str;
        str = "";
        continue;
      }
      str += line[i];
    }
    
    // $GPGGAセンテンスのみ読み込む
    if (list[0] == "$GPGGA") {
      
      // ステータス
      if(list[6] != "0"){
        Serial.println("start");
        
        //緯度
        Serial.println(NMEA2DD(list[2].toFloat()));
        
        //経度
        Serial.println(NMEA2DD(list[4].toFloat()));
        
        //温度
        val1=analogRead(0);
        Serial.println(temp);

        //電圧
        val2=analogRead(1);
        vol = val2 * 0.00488281 * 11 ;
        Serial.println(vol);
  
        Wire.requestFrom(8,1);
        while (Wire.available()) {
          long c = Wire.read();
          Serial.println(c);
          }

      }else{
        Serial.println("start");
        
        //緯度
        Serial.println("error");

        //経度
        Serial.println("error");
        
        //温度
        val1=analogRead(0);
        Serial.println(temp);
        
        //電圧
        val2=analogRead(1);
        vol = val2 * 0.00488281 * 11 ;
        Serial.println(vol);
        
        Wire.requestFrom(8,1);
        while (Wire.available()) {
          long c = Wire.read();
          Serial.println(c);
      }
    }
  }
 }
}


Raspberry Pi

from serial import *
from sys import exit
from datetime import datetime
import pygame
import datetime,time
import requests

from pygame.locals import *
import sys

SCREEN_SIZE = (640, 480)
url = 'https://xxx.jp/yyy/update.php'

def addTime(logtext):
return str(datetime.datetime.now()) + ' ,' + logtext

def retime():
if(retime1 >= 50):
if(retime2 >= 50):
return "0" + str(59-retime2) + ":" + "0" + str(59-retime1)
elif(retime2 < 50):
return str(59-retime2) + ":" + "0" + str(59-retime1)
elif(retime1 < 50):
if(retime2 >= 50):
return "0" + str(59-retime2) + ":" + str(59-retime1)
elif(retime2 < 50):
return str(59-retime2) + ":" + str(59-retime1)


pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE)
pygame.display.set_caption("data")

# ArduinoのUSBデバイス名
port = '/dev/ttyACM0'

# フォントの作成
sysfont = pygame.font.SysFont(None, 80)

# シリアルポートを開く
try:
ser = Serial(port, 9600)
print('open port: %s' % port)
except:
print('cannot open port: %s' % port)
exit(1)

f = open("write.txt","w")
f.write(addTime("start\n"))
f.close()


# 読み出しと出力
while True:
line = ser.readline().rstrip().decode("utf-8")
if(line=="start"):

# 1ライン単位で読み出し、末尾の改行コードを削除
line1 = ser.readline().rstrip().decode("utf-8")
line2 = ser.readline().rstrip().decode("utf-8")
line3 = ser.readline().rstrip().decode("utf-8")
line4 = ser.readline().rstrip().decode("utf-8")
line5 = ser.readline().rstrip().decode("utf-8")


payload = {"speed":line5,"temp":line3,"volt":line4}
response = requests.get(url,params=payload)
# テキストを描画したSurfaceを作成
text1 = sysfont.render("North", True, (0,0,0))
text2 = sysfont.render("East", True, (0,0,0))
text3 = sysfont.render("Temp", True, (0,0,0))
text4 = sysfont.render("Volt", True, (0,0,0))
text5 = sysfont.render("Speed", True, (0,0,0))
data1 = sysfont.render(line1, True, (0,0,0))
data2 = sysfont.render(line2, True, (0,0,0))
data3 = sysfont.render(line3, True, (0,0,0))
data4 = sysfont.render(line4, True, (0,0,0))
data5 = sysfont.render(line5, True, (0,0,0))

f = open("write.txt","a")
f.write("North,")
f.write(line1)
f.write(", Eeat,")
f.write(line2)
f.write(", Temp,")
f.write(line3)
f.write(", Volt,")
f.write(line4)
f.write(", Speed,")
f.write(line5)
f.write(",\n")
f.close()

try:
screen.fill((255,255,255))

# テキストを描画する
screen.blit(text1, ( 0, 50))
screen.blit(data1, (200, 50))
screen.blit(text2, ( 0,100))
screen.blit(data2, (200,100))
screen.blit(text3, ( 0,150))
screen.blit(data3, (200,150))
screen.blit(text4, ( 0,200))
screen.blit(data4, (200,200))
screen.blit(text5, ( 0,250))
screen.blit(data5, (200,250))

pygame.display.update()
except Exception as e:
print(e.message)



for event in pygame.event.get():
if event.type == QUIT:
sys.exit()

プログラム自体は今までやってきたものの組み合わせでした。

 本番のこととかはこちら

 まあ、これでひと段落したので、Pygameで作っているパックマンを完成させて、その後にライントレーサーのIoT化とかをやっていきたいと思います。
 あと、インバーターとかも作ります。それではまた今度。

ラズパイをUltraVNCでパソコンから操作した話

 サークルで作っているセンサーのシステムで、バイク本体に乗せているラズパイをほかのデバイスから操作できたほうが便利です。それなので、今回はまずパソコンで操作できるようにしました。


・使ったソフト
 今回は導入が手軽だったので、UltraVNCというものを使いました。


・ラズパイの操作
 ラズパイの操作としては以下の手順をすることになります。
% sudo apt-get install x11vnc
% x11vnc -storepasswd
③% ifconfig
④% x11vnc -usepw

①このコマンドでインストールします。いくつかの質問が来ますが、基本すべてエンターで流しておけば大丈夫です。
②このコマンドで接続するときのパスワードを設定します。
③このコマンドでは、ラズパイのIPアドレスを見ることができます。
④このコマンドで起動することができます。PORT=xxxxと4桁の数字が表示されますが、この数字は後でパソコンで使います。


・パソコンの操作
 パソコンでの操作としてはこのサイトからソフトをダウンロードしてきてインストールします。
 インストールしてきたらUltraVNC Viewerを起動します。起動したらVNC serverに”IPアドレス:ポート番号”となるように入力しConnectをクリックします。そうするとパスワードを聞かれるので先ほど設定したパスワードを入力するとラズパイの画面が表示されます。


・動作
 実際に動かすとこのようにラズパイを操作することができました。
DrI-zwTVAAAS4-v

 今回はパソコンとラズパイを直接つないでしまいましたが、API,WebIOPiなどでもしてみたいです。それではまた今度。

最小構成?のArduinoを作った話

 なんとなく今までやれていなかった自作Arduinoを作りました。

・回路図
Arduino_回路図
 今回はこのような回路を作りました。ICのVCCに給電できてなかったり、AGNDがGNDに短絡してなかったりしますが動いたので問題はないはずです...
 ATMEGA328pにArduinoを書き込むのが面倒だったので、家で余ってるArduinoから抜いてきました。

 ただし、最小構成で作った場合シリアル通信ができないため、プログラムを書き込むことができなかったりシリアルモニタが使えなかったりしますが、まああまり困らないと思います。


 今日は暇で進捗が出たので二本も記事を書いてしまいましたが、まあまた忙しくなるのでこのままのペースではいきません。それではまた今度。
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

読者登録
LINE読者登録QRコード