今回もラズパイの記事です。いや~まじ楽しいです。
楽しいけど、あまりにもソロギターと畑違いなので、Youtubeのチャンネルを分けてみました。
ラズパイの動画を連続でアップしていたら、チャンネル登録者数が減少しましたので^^;
パッシブブザー
電子工作としては、たんにPNPトランジスターを使ったスイッチ回路というものなのでしょうか。
ラズパイで周波数を伴った電気がランジスターに流れると、その周波数を受け取った電気が違う足からも流れるのかな。
付属CDでは、トランジスターの原理を説明していないので、適当な事を書いていますが・・・ちょっと調べてみますか。
S8550 PNPトランジスターの役割
う~ん、電子工作素人が読んでも分からない記事ばかりです^^;
どうもS8550にはNPN型のS8050という兄弟がおり、SとSSはアメリカ製、C8550はインド製、で、お決まりの中国のパチものはS8550と同じ名称ですが、性能は相当低いようです。(このセット品のはたぶん中華でしょうね)
なぜ沢山種類のあるトランジスターの中で、この品番を使用しているのかですが、「この大きさで、流せれる電流が大きい」「PWM 信号を与えて制御をする場合、コンプリメンタリー特性を利用」だそうです。
難解ですね。コンプメンタリー特性ってなんやねん。と調べてみたところ、今回のパッシブブザーではトランジスターを1個しか使用していないから、PNPとNPNを使った周波数の増幅?には関係ないようですね。
ま~多分、「大きめの電流を流しても壊れない」というのが、この品番を使っている理由でしょうか・・・。
で、肝心のトランジスターの仕組みですが、ベース設置とエミッタ設置で、増幅度が違う・・・、今回のパッシブブザーはどちらになるのやら^^;;
難しいですな~。Google先生の紹介するサイト記事、少々難しいです。理系の人が説明記事を書くと、やたらと専門用語と、ディープな内容を突き詰めていく内容ですね。もっと、シンプルな説明記事ないかな~。
今度本屋さんに行って、実際に分かりやすそうな電子工作の本でも買ってこようかな。
とりあえずプログラム
ま~難しい操作原理は置いておいて、付属CDのプログラムを手打ちしました(前回のLCD1602液晶を使いたいため)。
動かしてみると、なんともショボい曲?なのか、なんなのか分からない曲が流れます。
一つだけ、プログラムに不明点がありまして、なぜか配列の0番目を使わない記述でした。。繰り返しの数字が range(1,変数)となっていまして、0スタートでなく、1スタートになっていました。
この部分、自分で「君をのせて」をデーター入力して実際に演奏させたときに???なんか変だなと思い気づいたのですが、・・・どこか見落としがあるかな。
プログラムのアレンジ
参考プログラムの曲が微妙でしたので、「君をのせて」を楽譜を見ながらデーター打ち。今回の動画の長さ分の打ち込みで1時間以上かかりました。
ドレミの音階よりも、LCD液晶に表示させるカタカナをコード変換するのが超大変。おそらくア~ンまでの、2次元配列変数を作ったほうが早かったぐらいの作業量でした^^;
時折試し再生をすると、どうにも音痴な感じでしたので、ネットでドレミ周波数を調べて、小数点3位まで記述しました。整数でないとエラーが出るのかと思いましたが、特にエラーは出ませんでした。実際の楽器では、440Hzと441Hzではかなり音が違いますからね~。
楽譜上に出てくるF#とG#も加えて、今回の演奏となっています。
LCDのオリジナル顔文字もリニューアル
前回と比べて、猫っぽくなりました。どちらかと言えば犬っぽいですが。
余裕がでたら、目、耳とか、髭とかで表情を表せれるようにしたいですね^^
使用プログラム(Python)
import smbus import RPi.GPIO as GPIO import time import threading I2C = smbus.SMBus(1) #1番のI2Cバスを指定 I2C_add = 0x27 #LCDに付属のインターフェイスのアドレス CODE_RS0 = 0b0000000 #LCDのRS (レジスタの選択 0=命令用) CODE_RS1 = 0b0000001 #LCDのRS (レジスタの選択 1=書き込み用) CODE_E = 0b0000100 #LCD Enable 1から0になると、LCDの制御ICがデータ処理実行 CODE_LED = 0b00001000 #LCDのバックライト 1点灯 0消灯 mojisuu = 16 #ディスプレイの横文字数 (空白で埋めるために使用) LINE1 = 0x80 #上段の左端アドレス 0x80 ~ 0x8f までの16文字分 LINE2 = 0xC0 #下段の左端アドレス 0xc0 ~ 0xcf までの16文字分 LIN8C = 0x80 #文字表示任意の場所を指定用 上段の5番目 0x85 下段の12番目 0xcc等 counter = 0 timer1 = 0 time_sleep = 1 hennsuu = 0 #GPIO setup def GPIO_setup(): GPIO.setwarnings(False) #セットアップ前のエラー非表示 GPIO.setmode(GPIO.BCM) #GDIOピンの指定方法 GPIO.setup(26,GPIO.OUT) #GPIO.LOW=0=False initial=GPIO.LOW 7seguLED GPIO.output(26,GPIO.HIGH) global Buzz Buzz = GPIO.PWM(26,440) Buzz.start(50) global timer1 global time_sleep timer1 = threading.Timer(time_sleep,timer) timer1.start() def timer(): global counter global timer1 global time_sleep timer1 = threading.Timer(time_sleep,timer) timer1.start() counter += 1 #LIN8C = 0x85 #LCD_print=(str(counter)+'s') #LCD_moji(LCD_print,LIN8C) #LIN8C = 0xc5 #kanacode = [0xb6,0x0c4,0xde,0xb3,0xc1,0xad,0xb3] #LCD_katakana(kanacode,LIN8C) def I2C_write(bits,mode): data = (bits & 0xF0) | mode | CODE_LED I2C.write_byte_data(I2C_add,(data | CODE_E),(data)) time.sleep(0.0002) data = ((bits << 4) & 0xF0) | mode | CODE_LED I2C.write_byte_data(I2C_add,(data | CODE_E),(data)) time.sleep(0.0002) def LCD_set():#初期設定 4ビットへの設定 data = (0x33 & 0xF0) | 0x00 | CODE_LED I2C.write_byte_data(I2C_add,(data | CODE_E),(data)) time.sleep(0.005)#0.004以上あける。 I2C.write_byte_data(I2C_add,(data | CODE_E),(data)) time.sleep(0.0002)#0.00001以上あける startcom = [0x32,0x28,0x0c,0x01,0x02] for command in startcom: I2C_write(command,CODE_RS0) I2C_write(0x06,CODE_RS0) def LCD_clear():#画面クリア clearcom = [0x0c,0x01,0x02,0x06] for command in clearcom: I2C_write(command,CODE_RS0) time.sleep(0.0008) def LCD_text(message,line):#指定した行にまとめてmessage書き込み message =message.center(mojisuu," ") #左,右寄せ、中央 ほかを空白で埋める rjust, ljust, center I2C_write(line,CODE_RS0)#行を指定 上0x80 か 下0xc0 で左端から for i in range(mojisuu): I2C_write(ord(message[i]),CODE_RS1)#LCDのRSを1、文字コード指定 。これを行う前に行(列81=8fも可能)の指定が必要 def LCD_moji(message,line):#指定した場所にmessage書き込み(上書き) I2C_write(line,CODE_RS0)#位置を指定 上0x80 か 下0xc0 で左端から for i in range (len (message)): I2C_write(ord(message[i]),CODE_RS1) def LCD_katakana(message,line):#指定した場所にmessage書き込み(上書き) I2C_write(line,CODE_RS0)#位置を指定 上0x80 か 下0xc0 で左端から for i in range (len (message)): I2C_write(message[i],CODE_RS1) def LCD_tuiki(message):#LED_mojiのあとの追記用 for i in range (len (message)): I2C_write(ord(message[i]),CODE_RS1) def LCD_l_move(kazu,hayasa):#文字を左へスクロール 変数kazu分 早は変数hayasa I2C_write(0x0c,CODE_RS0)#カーソル表示OFF I2C_write(0x07,CODE_RS0)#シフト機能ON for i in range (kazu): I2C_write(0x18,CODE_RS0) time.sleep(hayasa) I2C_write(0x06,CODE_RS0)#シフト機能OFF I2C_write(0x02,CODE_RS0)#カーソル戻す def LCD_r_move(kazu,hayasa):#文字を右へスクロール 変数kazu分 早は変数hayasa I2C_write(0x0c,CODE_RS0)#カーソル表示OFF I2C_write(0x07,CODE_RS0)#シフト機能ON for i in range (kazu): I2C_write(0x1C,CODE_RS0) time.sleep(hayasa) I2C_write(0x06,CODE_RS0)#シフト機能OFF I2C_write(0x02,CODE_RS0)#カーソル戻す def LCD_back(kazu): for i in range (0,kazu): I2C_write(0x10,CODE_RS0)#左にカーソル戻す def LCD_insert(message,hayasa):#入力した際に、文字を左へスクロール カーソルの位置固定 I2C_write(0x07,CODE_RS0)#シフト機能ON for i in range (len (message)): I2C_write(ord(message[i]),CODE_RS1)#LCDのRSに1、文字指定 time.sleep(hayasa) I2C_write(0x06,CODE_RS0)#シフト機能OFF I2C_write(0x02,CODE_RS0)#カーソル戻す def LCD_original(): I2C_write(0x40,CODE_RS0) #オリジナル文字 1文字目のアドレス指定 #2文字目は0b01001000 0x48 #3文字目は0b01010000 0x50、以降0x58 0x60 0x68 0x70 0x78 の計8文字 # 0bxxx00000 左3ビット使わない 5*7ドット I2C_write(0b00100,CODE_RS1) I2C_write(0b01010,CODE_RS1) I2C_write(0b10001,CODE_RS1) I2C_write(0b10000,CODE_RS1) I2C_write(0b01000,CODE_RS1) I2C_write(0b00000,CODE_RS1) I2C_write(0b00000,CODE_RS1) I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み I2C_write(0b00001,CODE_RS1) I2C_write(0b01000,CODE_RS1) I2C_write(0b10000,CODE_RS1) I2C_write(0b01100,CODE_RS1) I2C_write(0b10010,CODE_RS1) I2C_write(0b10010,CODE_RS1) I2C_write(0b011100,CODE_RS1) I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み I2C_write(0b11000,CODE_RS1) I2C_write(0b00001,CODE_RS1) I2C_write(0b00000,CODE_RS1) I2C_write(0b01100,CODE_RS1) I2C_write(0b10010,CODE_RS1) I2C_write(0b10010,CODE_RS1) I2C_write(0b11100,CODE_RS1) I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み I2C_write(0b00100,CODE_RS1) I2C_write(0b01010,CODE_RS1) I2C_write(0b10010,CODE_RS1) I2C_write(0b00010,CODE_RS1) I2C_write(0b00100,CODE_RS1) I2C_write(0b01000,CODE_RS1) I2C_write(0b10000,CODE_RS1) I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み I2C_write(0b00110,CODE_RS1) I2C_write(0b01000,CODE_RS1) I2C_write(0b00011,CODE_RS1) I2C_write(0b00100,CODE_RS1) I2C_write(0b01001,CODE_RS1) I2C_write(0b00010,CODE_RS1) I2C_write(0b00000,CODE_RS1) I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み I2C_write(0b00000,CODE_RS1) I2C_write(0b01000,CODE_RS1) I2C_write(0b10000,CODE_RS1) I2C_write(0b10001,CODE_RS1) I2C_write(0b01110,CODE_RS1) I2C_write(0b00000,CODE_RS1) I2C_write(0b00001,CODE_RS1) I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み I2C_write(0b00000,CODE_RS1) I2C_write(0b00010,CODE_RS1) I2C_write(0b00001,CODE_RS1) I2C_write(0b10010,CODE_RS1) I2C_write(0b01100,CODE_RS1) I2C_write(0b00000,CODE_RS1) I2C_write(0b10000,CODE_RS1) I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み I2C_write(0b01100,CODE_RS1) I2C_write(0b00000,CODE_RS1) I2C_write(0b11000,CODE_RS1) I2C_write(0b00100,CODE_RS1) I2C_write(0b10000,CODE_RS1) I2C_write(0b01000,CODE_RS1) I2C_write(0b00000,CODE_RS1) I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み def LCD_led():#LEDライトの消灯 CODE_LED = 0 data = (0 & 0xF0) | CODE_RS0 | CODE_LED I2C.write_byte_data(I2C_add,(data | CODE_E),(data)) time.sleep(0.0002) #命令を2回流さないと、4ビットのずれが出てバグる data = (0 & 0xF0) | CODE_RS0 | CODE_LED I2C.write_byte_data(I2C_add,(data | CODE_E),(data)) time.sleep(0.0002) def LCD_neko(): LCD_text('Carrying You',LINE1) LCD_text('Castle in Sky',LINE2) time.sleep(3) LCD_clear() LIN8C = 0x80 kanacode = [0x00,0x01,0x02,0x03] LCD_katakana(kanacode,LIN8C) LIN8C = 0xc0 kanacode = [0x04,0x05,0x06,0x07] LCD_katakana(kanacode,LIN8C) def destroy(): timer1.cancel() Buzz.stop() GPIO.output(26,GPIO.HIGH) time.sleep(0.4) LCD_print=('--end--') LCD_moji(LCD_print,0x85) time.sleep(2) LCD_r_move(16,0.4) LCD_clear() LCD_led() GPIO.cleanup() print ('end') def main(): for j in range(0,len(kasi_1)): LIN8C = 0xc4 kanacode = kasi_1[j] LCD_katakana(kanacode,LIN8C) for i in range(0, len(song_1[j])): Buzz.ChangeFrequency(song_1[j][i]) time.sleep(beat_1[j][i] * 0.3) # delay a note for beat CL = [1, 131, 147, 165, 175, 196, 211, 248] # Frequency of Bass tone in C major CM = [1, 261.626, 293.665, 329.628, 349.228, 369.994, 391.995, 415.305, 440, 493.883] # Frequency of Midrange tone in C major CH = [1, 523.251, 587.330, 659.255, 698.456, 783.991, 880, 987.767] # Frequency of Treble tone in C major song_1 = [[CM[8],CM[9],CH[1],CM[9],CH[1],CH[3],CM[9],CM[0]], [CM[3],CM[8],CM[6],CM[8],CH[1],CM[6],CM[0]], [CM[3],CM[3],CM[4],CM[3],CM[4],CH[1],CM[3]], [CH[1],CH[1],CH[1],CM[9],CM[5],CM[5],CM[9],CM[9],CM[0]], [CM[0],CM[8],CM[9],CH[1],CM[9],CH[1],CH[3],CM[9],CM[0]], [CM[3],CM[3],CM[8],CM[6],CM[8],CH[1],CM[6],CM[0]], [CM[3],CM[4],CH[1],CM[9],CH[1],CH[2],CH[2],CH[3],CH[1]], [CH[1],CM[9],CM[8],CM[8],CM[9],CM[7],CM[8]], [CH[1],CH[2],CH[3],CH[2],CH[3],CH[5],CH[2],CH[0]], [CM[6],CM[6],CH[1],CM[9],CH[1],CH[3],CH[3],CH[0]], [CM[8],CM[9],CH[1],CM[9],CH[1],CH[2],CH[2],CH[1],CM[6],CM[6]], [CH[4],CH[3],CH[2],CH[1],CH[3],CH[0]], [CH[3],CH[6],CH[5],CH[5],CH[3],CH[2],CH[1]], [CH[1],CH[2],CH[1],CH[2],CH[5],CH[3],CH[0]], [CH[3],CH[6],CH[5],CH[3],CH[2],CH[1]], [CH[1],CH[2],CH[1],CH[2],CM[9],CM[8],CH[0]], [CM[8],CM[9],CH[1],CM[9],CH[1],CH[3],CM[9],CM[0]], [CM[3],CM[8],CM[6],CM[8],CH[1],CM[6],CM[0]], [CM[3],CM[3],CM[4],CM[3],CM[4],CH[1],CM[3]], [CH[1],CH[1],CH[1],CM[9],CM[5],CM[5],CM[9],CM[9],CM[0]], [CM[0],CM[8],CM[9],CH[1],CM[9],CH[1],CH[3],CM[9],CM[0]], [CM[3],CM[3],CM[8],CM[6],CM[8],CH[1],CM[6],CM[0]], [CM[3],CM[4],CH[1],CM[9],CH[1],CH[2],CH[2],CH[3],CH[1]], [CH[1],CM[9],CM[8],CM[8],CM[9],CM[7],CM[8]]] beat_1 = [[1,1,3,1,2,2,5,2], [2,3,1,2,2,4,1], [3,1,3,1,1,3,6], [1,1,1,3,1,2,2,3,1], [2,1,1,3,1,2,2,3,1], [2,1,3,1,2,2,2,3], [3,2,1,3,2,1.5,2.5,1,3], [2,1,1,1,2,2,6], [1,1,3,1,2,2,3,3], [1,1,3,1,2,2,7,1], [1,1,2,1,1,1,1,3,1,4], [2,2,2,2,10,3], [3,4,3,1,1,1,5], [1,2,1,2,3,5,1], [2,4,4,1,1,5], [1,2,1,3,2,5,1], [1,1,3,1,2,2,5,2], [2,3,1,2,2,4,1], [3,1,3,1,1,3,6], [1,1,1,3,1,2,2,3,1], [2,1,1,3,1,2,2,3,1], [2,1,3,1,2,2,2,3], [3,2,1,3,2,1.5,2.5,1,3], [2,1,1,1,2,2,6]] kasi_1 = [[0xb1,0xc9,0xc1,0xcd,0xb2,0xbe,0xdd], [0xb6,0xb6,0xde,0xd4,0xb8,0xc9,0xca], [0xc4,0xde,0xba,0xb6,0xc6,0xb7,0xd0,0xa6], [0xb6,0xb8,0xbc,0xc3,0xb2,0xd9,0xb6,0xd7], [0xc0,0xb8,0xbb,0xdd,0xc9,0xcb,0xb6,0xde], [0xc5,0xc2,0xb6,0xbc,0xb2,0xc9,0xca,0x20], [0xb1,0xc9,0xc4,0xde,0xda,0xb6,0xcb,0xc4,0xc2,0xc6], [0xb7,0xd0,0xb6,0xde,0xb2,0xd9,0xb6,0xd7,0x20,0x20], [0xbb,0xb1,0xc3,0xde,0xb6,0xb9,0xd6,0xb3], [0xcb,0xc4,0xb7,0xda,0xc9,0xca,0xdf,0xdd], [0xc5,0xb2,0xcc,0xd7,0xdd,0xcc,0xdf,0xb6,0xca,0xde,0xdd,0xc6], [0xc2,0xd2,0xba,0xdd,0xc3,0xde,0x20,0x20,0x20,0x20,0x20,0x20], [0xc4,0xb3,0xbb,0xdd,0xb6,0xde,0xc9,0xba,0xbc,0xc0], [0xb1,0xc2,0xb2,0xb5,0xd3,0xb2,0x20,0x20,0x20,0x20], [0xb6,0xb1,0xbb,0xdd,0xb6,0xde,0xb8,0xda,0xc0], [0xb1,0xc9,0xcf,0xc5,0xbb,0xde,0xbc,0x20,0x20], [0xc2,0xb7,0xad,0xb3,0xca,0xcf,0xdc,0xd9], [0xb7,0xd0,0xa6,0xb6,0xb8,0xbc,0xc3,0x20], [0xb6,0xb6,0xde,0xd4,0xb8,0xcb,0xc4,0xd0], [0xb7,0xd7,0xd2,0xb8,0xc4,0xd3,0xbc,0xcb,0xde], [0xc2,0xb7,0xad,0xb3,0xca,0xcf,0xdc,0xd9,0x20], [0xb7,0xd0,0xa6,0xc9,0xbe,0xc3,0x20,0x20], [0xb2,0xc2,0xb6,0xb7,0xaf,0xc4,0xc3,0xde,0xb1,0xb3], [0xce,0xde,0xb8,0xd7,0xa6,0xc9,0xbe,0xc3,0x20,0x20] ] LCD_set() LCD_original() LCD_neko() GPIO_setup() main() destroy()
コメント
コン太郎さん、新年おめでとうございます。
ラズパイとはまた奇妙なもののはまっていますね。私は名前すら知りませんでした。
正直今回の動画も、演奏内容よりも猫たちが気になってしょうがないです(笑)。
2匹とも元気そうですね。
こっちも元気ですが、そろそろ避妊手術の時期なのに、かわいそうなんで引き伸ばしてばかりいます・・・。
J minorさん、こんばんわ、今年もよろしくお願いします。
ラズパイ知ったのは私も最近ですが、おもちゃの一種だと思って楽しんでいます。
猫たち、病院行くのすごい嫌がるんですよね~。そして病院の匂いを漂わせるユパさんに、3日ほどテトは威嚇していまし^^
避妊うんぬんは難しいですよね~、うちは雄二匹なので避妊というよりも、部屋にマーキングされるのが困るという1番の理由ですかね。泌尿系の病気にもなってもらいたくないし。
環境とお金がゆるすなら、どんどん増えてもらいたい!?です^^