久々に電子工作をしました。
母校の小学校がとうとう閉校になるので、何か記念になるものを残しておこうと思い校歌を電子オルゴールにしてみました。
PICマイコン12F629と圧電スピーカ、電池といった簡単な構成でできます。
写真にあるものは、CDSをつけて明るくなると鳴り出すように作ったので部品がCDSと抵抗2本が増えています。
開発はmikroBASICを使いました。
ライターはPICKit2。
MikroBasicのライブラリーにSOUNDがあり、音程と長さを指定して音を鳴らすことができます。
PIC12F629にはEEPROMがあります。このEEPROMに音程長さを記憶させておき順に読み込み音楽を演奏させています。
そのままでは音程と長さで4バイト必要になりますが、プログラム内部でドレミと音符の長さのテーブルを持ち、EEPROMにはその番号のみで上位4ビットで長さ、下位4ビットで音程の番号を表現させました。
EEPROMの内容は校歌なので載せてもと思い、ソースのみを公開します。
休符の扱いがわからずDelayで表現しています。
Delayはライブラリーで実装されておらず、パラメータに変数が使えないので4分休符のみのコーディングです。
調子に乗ってコーディングしていたら、プログラムエリアが足りなくなりました。
SOUNDとEEPROMのライブラリーで結構メモリーを食ってしまっているようです。
program MUSIC
' 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
' R C C# D D# E F F# G G# A A# B C C# D
const doremi as word[16]= ( 0,262,277,294,311,330,349,370,392,415,440,466,494,523,554,587)
' tempo=120
' 0 1 2 3 4 5 6 7 8 9
' 1 2. 2 4. 4 8. 8 16. 16
const onpu as word[9]= (2000,1500,1000,0750,0500,0375,0250,0188,0125)
' Declarations section
sub procedure init_rtn
GPIO = 0
CMCON = 000111
TRISIO = 000000
'ANSEL = 000000
Sound_Init(GPIO, 2)
end sub
main:
dim eromdt as byte
dim takapt as byte
dim nagapt as byte
dim takasa as word
dim nagasa as word
dim yasumi as word
dim i as byte
init_rtn
while true
i=0 'EPROM READ POINTER
while < 127 'EPROM MAC ADDRESS 128
eromdt = EEPROM_Read(i) 'DATA READ FROM EPROM
if eromdt = $FF then 'DATA VALUE FF is END of DATA
i =128 'Exit Loop When set 128
else
takapt = eromdt and $0f 'DATA low4bit is SOUND Pitch
nagapt = eromdt >> 4 'DATA High4bit is SOUND Length
if takapt = 0 then
'select case nagapt
' case 4
Delay_ms(500)
' case 2
' delay_ms(1000)
' case 0
' delay_ms(2000)
'end select
else
takasa = doremi[takapt]'Pitch Table
nagasa = onpu[nagapt]
Sound_Play(takasa,nagasa)
Delay_ms(16)
end if
end if
i=i+1
wend
'ENTRY SLEEP '
GPIO =0
OPTION_REG = 000000
INTCON = %10001000'
NOP
NOP
asm
sleep
end asm
NOP
NOP
'RESUME SLEEP
INTCON = 000000
wend
end.