Vermes
Advanced Member level 4
This music box was designed for educational purpose, so it has no form nor a housing. Test circuit was mounted on a contact board. The device is supplied by visible in pictures USBasp programmer from USB port.
Some significant features:
- a speaker is connected in series to the microcontroller via a capacitor
- software written in AVR assembler 2
- Fast PWM Toggle On Compare OutA mode was used, so there is not an interruption from Timer1 – output pin is fixed rigid on PORTB1
- code can be moved into any microcontroller Atmega
- format of data to enter was adapted to conversion from RTTL (conversion under Linux by a script in bash; a converted melody can be found under each of buttons and the source code contains description of mode)
- the value of oscillator is not imposed, you can use any crystal quartz from 4MHz to 16MHz, just adjust this value to the right in the line:
Code:
#define F_CPU* *11059200
In this project, resonator 11,0592MHz was used. Do not forget to set fusebits to an external oscillator, so the melodies can be played in right speed and mode.
Here is the script of melody conversion:
Code:
#!/bin/bash
INPUT_MEM=$(cat "${1}" | tr -d '\n' | tr -d '\r')
Tittle=$(echo ${INPUT_MEM} | sed -n 's/\(.*\)\:.*\:.*/\1/p')
echo "; Tytuł: ${Tittle}"
Defaults=$(echo ${INPUT_MEM} | sed -n 's/.*\:\(.*\)\:.*/\1/p' | sed 's/\,/\ /g')
echo "; Wartości Domyślne:"
for Default in ${Defaults}; do
case "${Default}" in
d=*)
Default_duration=$(echo ${Default} | sed -n 's/d=\(.*\)/\1/p')
echo -e ";\tNuta domyślna to 1/${Default_duration}"
;;
o=*)
Default_octave=$(echo ${Default} | sed -n 's/o=\(.*\)/\1/p')
echo -e ";\tOktawa podstawowa to ${Default_octave}"
;;
b=*)
Default_tempo=$(echo ${Default} | sed -n 's/b=\(.*\)/\1/p')
Default_tempo_s=$[${Default_tempo}/60]
echo -e ";\tTaktów : ${Default_tempo}/min = ${Default_tempo_s}/s.\n;\tW całej nucie mieszczą się 4 takty."
;;
esac
done
Notes=$(echo ${INPUT_MEM} | sed -n 's/.*\:.*\:\(.*\)/\1/p' | sed 's/\,/\ /g')
BASE_PERIOD_MS="10"
echo "; Nuty:"
for NoteP in ${Notes}; do
# Catch dot note *1,5 duration
_pd="$(echo ${NoteP} | sed -n 's/.*[aAbBcCdDeEfFgGpP]#*\(\.\)*.*/\1/p')"
Note=$(echo ${NoteP} | sed -n 's/\(.*[aAbBcCdDeEfFgGpP]#*\)\(\.\)*\(.*\)/\1\3/p')
case "${Note}" in
*[pP]*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[pP].*/\1/p')
_octave="_"
_asm_note="_P"
*
;;
*[aA]#*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[aA]#.*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[aA]#\(.*\)/\1/p')
_asm_note="_b"
;;
*[aA]*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[aA].*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[aA]\(.*\)/\1/p')
_asm_note="_a"
;;
*[bB]*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[bB].*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[bB]\(.*\)/\1/p')
_asm_note="_h"
;;
*[cC]#*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[cC]#.*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[cC]#\(.*\)/\1/p')
_asm_note="_cis"
;;
*[cC]*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[cC].*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[cC]\(.*\)/\1/p')
_asm_note="_c"
;;
*[dD]#*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[dD]#.*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[dD]#\(.*\)/\1/p')
_asm_note="_dis"
;;
*[dD]*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[dD].*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[dD]\(.*\)/\1/p')
_asm_note="_d"
;;
*[eE]#*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[eE]#.*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[eE]#\(.*\)/\1/p')
_asm_note="_f"
;;
*[eE]*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[eE].*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[eE]\(.*\)/\1/p')
_asm_note="_e"
;;
*[fF]#*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[fF]#.*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[fF]#\(.*\)/\1/p')
_asm_note="_fis"
;;
*[fF]*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[fF].*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[fF]\(.*\)/\1/p')
_asm_note="_f"
;;
*[gG]#*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[gG]#.*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[gG]#\(.*\)/\1/p')
_asm_note="_gis"
;;
*[gG]*)
_duration=$(echo ${Note} | sed -n 's/\(.*\)[gG].*/\1/p')
_octave=$(echo ${Note} | sed -n 's/.*[gG]\(.*\)/\1/p')
_asm_note="_g"
;;
esac
[ -z "${_duration}" ] && _duration="${Default_duration}"
[ -z "${_octave}" ] && _octave="${Default_octave}"
Note_full="${_asm_note}${_octave}"
if [ -n "${_pd}" ]; then
PERIOD_MUL=$[36000/(${Default_tempo}*${_duration})]
else
PERIOD_MUL=$[24000/(${Default_tempo}*${_duration})]
fi
EXTRA_TAB=""
[ -z $(echo "${_asm_note}" | grep 'is') ] && EXTRA_TAB="\t"
echo -e ".db ${Note_full}, ${PERIOD_MUL}${EXTRA_TAB}\t; ${NoteP} (${PERIOD_MUL}0ms)"
done
echo ".db 0, 0"
*
It can be induced:
Code:
$ ./RTTTL2AVRasm "Beethoven - Fur Elise.rtl"*
; Tytuł: Beethoven - Fur Elise*
; Wartości Domyślne:*
;* * * *Nuta domyślna to 1/4*
;* * * *Oktawa podstawowa to 5*
;* * * *Taktów : 125/min = 2/s.*
;* * * *W całej nucie mieszczą się 4 takty.*
; Nuty:*
.db _e6, 24* * * * * * *; 8e6 (240ms)*
.db _dis6, 24* *; 8d#6 (240ms)*
.db _e6, 24* * * * * * *; 8e6 (240ms)*
.db _dis6, 24* *; 8d#6 (240ms)*
.db _e6, 24* * * * * * *; 8e6 (240ms)*
.db _h5, 24* * * * * * *; 8b (240ms)*
.db _d6, 24* * * * * * *; 8d6 (240ms)*
.db _c6, 24* * * * * * *; 8c6 (240ms)*
.db _a5, 48* * * * * * *; a (480ms)*
.db _P_, 48* * * * * * *; p (480ms)*
.db _c5, 24* * * * * * *; 8c (240ms)*
.db _e5, 24* * * * * * *; 8e (240ms)*
.db _a5, 24* * * * * * *; 8a (240ms)*
.db _h5, 36* * * * * * *; 8b. (360ms)*
.db _P_, 48* * * * * * *; p (480ms)*
.db _e5, 24* * * * * * *; 8e (240ms)*
.db _gis5, 24* *; 8g# (240ms)*
.db _h5, 24* * * * * * *; 8b (240ms)*
.db _c6, 36* * * * * * *; 8c.6 (360ms)*
.db _P_, 48* * * * * * *; p (480ms)*
.db _e5, 24* * * * * * *; 8e (240ms)*
.db _e6, 24* * * * * * *; 8e6 (240ms)*
.db _dis6, 24* *; 8d#6 (240ms)*
.db _e6, 24* * * * * * *; 8e6 (240ms)*
.db _dis6, 24* *; 8d#6 (240ms)*
.db _e6, 24* * * * * * *; 8e6 (240ms)*
.db _h5, 24* * * * * * *; 8b (240ms)*
.db _d6, 24* * * * * * *; 8d6 (240ms)*
.db _c6, 24* * * * * * *; 8c6 (240ms)*
.db _a5, 24* * * * * * *; 8a (240ms)*
.db _P_, 48* * * * * * *; p (480ms)*
.db _c5, 24* * * * * * *; 8c (240ms)*
.db _e5, 24* * * * * * *; 8e (240ms)*
.db _a5, 24* * * * * * *; 8a (240ms)*
.db _h5, 36* * * * * * *; 8b. (360ms)*
.db _P_, 48* * * * * * *; p (480ms)*
.db _d5, 24* * * * * * *; 8d (240ms)*
.db _c6, 24* * * * * * *; 8c6 (240ms)*
.db _h5, 24* * * * * * *; 8b (240ms)*
.db _a5, 48* * * * * * *; a (480ms)*
.db 0, 0
Pictures:
Link to original thread (useful attachment) - Pozytywka ATmega8 z możliwością zaprogramowania RTTL