' 28hammer -- plays tunes one note at a time & lights LED corresponding to note
#picaxe 28X2
' uses duration, octave, note coding from "tune" command
'eeprom 0,($29,$29,$2A,$00,$00,$2A,$29,$27,$25,$25,$27,$29,$29,$67,$E7,$29,$29,$2A,$00,$00,$2A,$29,$27,$25,$25,$27,$29,$27,$65,$E5,$27,$27,$29,$25,$27,$69,$6A,$29,$25,$27,$69,$6A,$29,$27,$25,$27,$2A,$E9,$29,$2A,$00,$00,$2A,$29,$27,$25,$25,$27,$29,$27,$65,$E5,$FF)
eeprom 0,("Ode To Joy",$FE,$29,$29,$2A,$00,$00,$2A,$29,$27,$25,$25,$27,$29,$29,$67,$E7,$29,$29,$2A,$00,$00,$2A,$29,$27,$25,$25,$27,$29,$27,$65,$E5,$27,$27,$29,$25,$27,$69,$6A,$29,$25,$27,$69,$6A,$29,$27,$25,$27,$25,$E9,$29,$2A,$00,$00,$2A,$29,$27,$25,$25,$27,$29,$27,$65,$E5,$FF,"Amazing Grace",$FE,$64,$69,$29,$41,$6B,$69,$01,$6B,$29,$66,$24,$64,$66,$29,$41,$6B,$69,$01,$6B,$41,$04,$41,$44,$04,$41,$6B,$69,$01,$6B,$29,$66,$24,$64,$66,$29,$41,$6B,$69,$01,$6B,$29,$FF,"Wildwood Flower",$FE,$66,$67,$29,$6B,$42,$26,$67,$66,$24,$67,$62,$22,$66,$67,$29,$6B,$42,$26,$67,$66,$24,$67,$41,$22,$29,$06,$46,$44,$02,$69,$69,$2B,$41,$6B,$29,$26,$26,$66,$64,$26,$69,$66,$24,$67,$21,$22,$FF,"Ashokan",$FE,$41,$02,$41,$4B,$49,$C6,$44,$46,$07,$46,$44,$42,$2B,$02,$6B,$29,$02,$06,$09,$02,$06,$06,$47,$06,$C4,$49,$41,$02,$41,$4B,$49,$C6,$44,$46,$07,$46,$44,$42,$2B,$02,$6B,$29,$02,$FF,$FF)
' BELOW: 1st row, # duplicate if > 1; 2nd row, notes ("-" if not available); 3rd row, note coding
' 2 2 2 3 2 2 2 2 2
' G3,-G#3,A3,-Bb3,B3,C4, C#4,D4,-Eb4, E4,F4, F#4,G4, G#4, A4,Bb4,B4, C5, C#5, D5,-Eb5,E5, F5,F#5, G5,-G#5,A5,-Bb5,B5, C6,-C#6,D6
'$00,$FF,$01,$FF,$02,$03,$10,$C0,$FF,$C1,$11,$12,$C2,$13,$C3,$20,$C4,$C5,$21,$C6,$FF,$C7,$22,$23,$C8,$FF,$30,$FF,$31,$32,$FF,$33
' Note coding: $FF=not available; $C?--pin C.0-C.7,A.0; other: 1st nybble is B-port string B0-B3; 2nd is B4-7
table 0,($00,$FF,$01,$FF,$02,$03,$10,$C0,$FF,$C1,$11,$12,$C2,$13,$C3,$20,$C4,$C5,$21,$C6,$FF,$C7,$22,$23,$C8,$FF,$30,$FF,$31,$32,$FF,$33)
table 40,("G3,-G#3,A3,-Bb3,B3,C4,C#4,D4,-Eb4,E4,F4,F#4,G4,G#4,A4,Bb4,B4,C5,C#5,D5,-Eb5,E5,F5,F#5,G5,-G#5,A5,-Bb5,B5,C6,-C#6,D6,",0,0,0)
symbol pButtonPin=pinA.2
symbol pLCD=A.3
symbol pPiezo=A.4
symbol newTune=bit0
symbol notech=b2
symbol lastch=b3
symbol eePtr=b4
symbol note=b5
symbol codedNote=b6
symbol pinNo=b7
symbol oldPinNo=b8
symbol octive=b9
symbol checkTime=b10
symbol tunePtr=b11
symbol LEDcoding=b12
symbol ch=b13
symbol noteNdxAdr = 56 ' start of upper ram; note text index
'amazing
'tune D.7, 15,($64,$69,$29,$41,$6B,$69,$01,$6B,$29,$66,$24,$64,$66,$29,$41,$6B,$69,$01,$6B,$41,$04,$41,$44,$04,$41,$6B,$69,$01,$6B,$29,$66,$24,$64,$66,$29,$41,$6B,$69,$01,$6B,$29)
'ode
'tune 5, 8,($29,$29,$2A,$00,$00,$2A,$29,$27,$25,$25,$27,$29,$29,$67,$E7,$29,$29,$2A,$00,$00,$2A,$29,$27,$25,$25,$27,$29,$27,$65,$E5
'tune 5, 8,($27,$27,$29,$25,$27,$69,$6A,$29,$25,$27,$69,$6A,$29,$27,$25,$27,$2A,$E9,$29,$2A,$00,$00,$2A,$29,$27,$25,$25,$27,$29,$27,$65,$E5)
settimer t1s_8 ' set timer to 1 second ticks at 8MHz (default speed)
newTune = 1
dirsB=%11111111 ' all outputs
pinsB=%00000000 ' all low
dirsB=%00000000 ' all inputs
dirsC=%11111111 ' all outputs
bptr = noteNdxAdr ' array of 35 byte pointers to note text
eePtr = 30 ' beginning of note-name data in table
readtable eePtr,ch
do while ch <> 0
@bptrinc = eePtr
readtable eePtr,ch
do while ch <> "," ' comma separated text
inc eePtr
readtable eePtr,ch
loop
inc eePtr
readtable eePtr,ch
loop
eePtr = 0
do
if newTune = 1 then
serout pLCD,N2400,(254,1) : pause 30 ' clear screen; see http://www.picaxe.com/docs/axe033.pdf
read eePtr, ch
do : serout pLCD,N2400,(ch) : inc eePtr : read eePtr, ch : loop until ch = $FE ' display name of selected tune
tunePtr = eePtr + 1
endif
do : loop while pButtonPin = 0 ' wait until button is pressed
timer = 0 ' one-second timer
checkTime=1
do : loop while pButtonPin = 1 ' wait until button is released
if timer <= checkTime then ' next tune
do : read eePtr, codedNote : inc eePtr : loop until codedNote = $FF ' read past this tune
read eePtr,ch
if ch = $FF then : eePtr = 0 : endif ' end of tunes; start over
newTune = 1
else ' we've selected this tune
serout pLCD,N2400,(254,192,"Playing")
eePtr = tunePtr
newTune = 0
read eePtr,codedNote
do while codedNote <> $ff
octive = codedNote & %00110000 >> 4 ' %00=middle; %01=high; %10=low
note = codedNote & %00001111
if octive = 0 then : note = note + 12 : endif ' middle octive
if octive = 1 then : note = note + 24 : endif ' high octive
pinNo = note ' 0-35: b.0-b.7, c.0-c.7, a.0-a.7, d.0-d.6 (D.7 plays tune)
' if pinNo > 17 then : pinNo = 17 : endif ' reserved pins: A.4=piezo; A.3=LCD; A.2=button
' low oldPinNo
' high pinNo
' oldPinNo = pinNo
readtable pinNo, LEDcoding
serout pLCD,N2400,(254,200) : pause 30 ' set cursor at row 2, position 8
bptr = pinNo + noteNdxAdr ' address of address in table of note text
bptr = @bptr ' get address in table of text
readtable bptr,ch
do while ch <> ","
serout pLCD,N2400,(ch)
inc bptr
readtable bptr,ch
loop
serout pLCD,N2400,(" ")
sertxd(#codedNote,"/",#pinNo,"/")
pinsB = %00000000 ' set all portB pins to low
dirsB = %00000000 ' set all portB pins inputs
pinsC = %00000000 ' set all portC pins to low
low D.0 '
if LEDcoding = $FF then ' invalid
elseif LEDcoding => $C0 then
pinNo = LEDcoding & %00000111 + 8 ' 8-16: C.0-C.7, A.0
high pinNo
pinNo = pinNo - 8
sertxd("C.",#pinNo," ")
else ' portB LED matrix control--
pinNo = LEDcoding / 16 & %00001111 ' 0-3: B.0-B.3: high pin for matrix
high pinNo
sertxd("B.",#pinNo,"-")
pinNo = LEDcoding & %00001111 + 4 ' 4-7: B.4-B.7: low pin for matrix
low pinNo
sertxd("B.",#pinNo," ")
endif
tune pPiezo,8,(codedNote)
inc eePtr
read eePtr,codedNote
if pButtonPin = 1 then ' terminate playing
serout pLCD,N2400,(254,192," ")
do while codedNote <> $FF : inc eePtr : read eePtr,codedNote : loop
do while pButtonPin = 1 : loop ' wait until released
endif
loop
serout pLCD,N2400,(254,192,"Done ")
endif
loop