1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

AVR & melody

Discussion in 'AVR' started by FreshMan, Oct 21, 2013.

  1. FreshMan

    FreshMan New Member

    Joined:
    Oct 21, 2013
    Messages:
    7
    Likes:
    0
    Location:
    Ukraine
    hi all :)
    I am a beginner in programming
    write in the language С
    please tell me how to play the elementary 8-bit melodies with the help of AVR ?
    or give good link
    thanks !
     
  2. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,160
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE
    AVR is a good choice for music.... It has 6 PWM outputs on the MEGA328 If you join AVRfeaks... There are many examples.
     
  3. FreshMan

    FreshMan New Member

    Joined:
    Oct 21, 2013
    Messages:
    7
    Likes:
    0
    Location:
    Ukraine
    I use the ATmega8
    I know that it is necessary to configure the T1 mode PWM
    but I don't understand how to convert the notes in the figures for the timer
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,160
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE

    I haven't really created music.... I have some example code at work.... That'll be tomorrow morning... I'll see what there is.
     
  6. Mike odom

    Mike odom Active Member

    Joined:
    Feb 21, 2010
    Messages:
    670
    Likes:
    52
    Location:
    Kansas City, KS, U.S.A.
    I'm not sure why you think you need a PWM to do music, other than they are good for frequencies, but so are timers. PWM give you the ability to adjust the duty cycle of the frequency, but we aren't worried about that on such a simple scale.

    Basically, a note is a frequency. Use your timer to produce a 1/2 cycle time period and toggle the output when the timer times out. You may even be able to use the timer overflow pin instead of toggling a port pin. This will give a square wave, which to the untrained ear, would be good enough to run into an audio amp.

    Now, I can see where you'd want to use the PWM function for controlling 6 notes at once. Use the PWM to set up the frequency, and set the duty cycle at 50%.
     
  7. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,160
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE
    To get 8 bit melodies you're going to need more than a pin toggle..... If a crappy sound is needed then yes!!
     
  8. misterT

    misterT Well-Known Member Most Helpful Member

    Joined:
    Apr 19, 2010
    Messages:
    2,697
    Likes:
    368
    Location:
    Finland
    You only need 1 pwm output if you use technique called Direct Digital Synthezis.
    http://www.youtube.com/watch?feature=player_detailpage&v=pGiD96zY7-M&list=PLD7F7ED1F3505D8D5#t=975
    There's more great lectures about the subject in this channel: www.youtube.com/playlist?list=PLD7F7ED1F3505D8D5

    I wrote an example program template for it: http://www.electro-tech-online.com/...up-table-microcontroller.138626/#post-1150259

    Here is a table of notes and their frequencies: www.seventhstring.com/resources/notefrequencies.html
     
    Last edited: Oct 22, 2013
  9. FreshMan

    FreshMan New Member

    Joined:
    Oct 21, 2013
    Messages:
    7
    Likes:
    0
    Location:
    Ukraine
    it's a bit complicated
    I have a project where all was implemented much easier ! :)
    there's only one difficulty for me
    I don't know how to convert the notes into the array ringtones
    Code (text):
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <avr/pgmspace.h>

    #define C1 15288
    #define C1d 14431
    #define D1 13621
    #define D1d 12856
    #define E1 12134
    #define F1 11453
    #define F1d 10811
    #define G1 10204
    #define G1d 9631
    #define A1 9090
    #define A1d 8580
    #define H1 8099
    #define C2 7648
    #define C2d 7220
    #define D2 6814
    #define D2d 6430
    #define E2 6069
    #define F2 5730
    #define G2 5102
    #define G2d 4815
    #define A2 4545
    #define A2d 4291
    #define H2 4049
    #define C3 3822
    #define P 0
    #define End 1
    #define N32 125.000
    #define N16 250.000
    #define N8 500.000
    #define N4 1000.000
    #define N2 2000.000
    #define N1 4000.000

    volatile int track=0;
    volatile int NoteLong = 250;
    volatile int loaded=0;
    volatile int i = 1;
    volatile int Bit = 0x00;

    volatile char flag;
    volatile int count=0;
    volatile char status = 1;


    int tanki[] PROGMEM={160.000,P,N32,C2,N32,D2,N32,D2d,N32,C2,N32,D2,N32,D2d,N32,D2d,N32,F2,N32,G2,N32,D2d,N32,F2,N32,G2,N32,F2,N32,G2,N32,A2,N32,F2,
                N32,G2,N32,A2,N32,G2d,N32,A2d,N32,C3,N32,G2d,N32,A2d,N32,C3,N32,C3,N32,P,N32,C3,N32,C3,N32,C3,N32,C3,N32,End}; //мелодия танчиков


    int mario[] PROGMEM={100.000,P,N16,E2,N32,E2,N32,P,N32,E2,N16,P,N32,C2,N32,E2,N32,P,N32,G2,N32,P,N32,P,N16,G1,N32,P,N16,P,N16,
                    C2,N32,P,N16,G1,N32,P,N16,E1,N16,P,N16,P,N32,A1,N32,P,N32,H1,N32,P,N32,A1d,N32,A1,N32,P,N32,
                    G1,N32,E2,N32,G2,N32,A2,N32,P,N32,F2,N32,G2,N32,P,N32,E2,N32,P,N32,C2,N32,D2,N32,H1,N32,End};  //мелодия марио


    int miniPolka[] PROGMEM={120.000,P,N16,C2,N16,E2,N16,G2,N16,E2,N16,G2,N16,F2,N16,D2,N8,G2,N16,F2,N16,D2,N8,G2,N16,E2,N16,C2,N8,
                    C2,N16,E2,N16,G2,N16,E2,N16,A2,N16,G2,N16,F2,N8,G2,N16,F2,N16,E2,N16,D2,N16,C2,N8,End};


    int bumer[] PROGMEM={170.000,P,N16,E2,N16,G2,N8,P,N8,P,N8,G2,N16,E2,N8,P,N8,P,N8,A2,N16,G2,N16,A2,N16,G2,N16,A2,N16,G2,N16,A2,N16,G2,N16,A2,N16,H2,N8,P,N8,End};


    int nokia[30] PROGMEM={120.000,P,N16,E2,N16,D2,N16,F1d,N8,G1d,N8,C2d,N16,H1,N16,D1,N8,E1,N8,H1,N16,A1,N16,C1d,N8,E1,N8,A1,N8,End};


    int mortal[66] PROGMEM={140.000,A1,N16,A1,N16,C2,N16,A1,N16,D2,N16,A1,N16,E2,N16,D2,N16,C2,N16,C2,N16,E2,N16,C2,N16,G2,N16,C2,N16,E2,N16,C2,N16,
                    G1,N16,G1,N16,H1,N16,G1,N16,C2,N16,G1,N16,D2,N16,C2,N16,F1,N16,F1,N16,A1,N16,F1,N16,C2,N16,F1,N16,C2,N16,H1,N16,End};


    int kuznechik[] PROGMEM={130.000,P,N16,A2,N8,E2,N8,A2,N8,E2,N8,A2,N8,G2d,N8,G2,N8,P,N8,G2d,N8,E2,N8,G2d,N8,E2,N8,G2d,N8,A2,N8,End};

    int *playlist[]={
                        kuznechik,
                        tanki,
                        mario,
                        mortal,
                        nokia,
                        miniPolka,
                        bumer
                    };


    //interrupt [TIM1_COMPA] void timer1_compa_isr(void)
    ISR (TIMER1_COMPA_vect)
    {
        PORTC^=(1<<1);
    }

    // Timer 2 overflow interrupt service routine
    ISR (TIMER2_OVF_vect)
    {
        if(count)count--;


    }

    void play()
    {
        OCR1AH = (char) (Bit >> 8);          //записываем новую ноту в OCR1A
        OCR1AL = (char) Bit;
        TIMSK |= 1 << OCIE1A;                // начали воспроизведение
        _delay_ms(NoteLong);                // длина ноты
        TIMSK &= ~(1 << OCIE1A);            //закончилась нота
        _delay_ms(40);
        i = i + 2;
    }

    void pause()
    {
        TIMSK &= ~(1<<OCIE1A);      // запрещаем прерывания
        _delay_ms(NoteLong);
        TIMSK |= 1<<OCIE1A;        // разрешаем прерывания
        i+=2;
    }


    void stop()
    {
        TIMSK &= ~(1<<OCIE1A);    // запрещаем прерывания
        Bit=0x00;
        PORTC&=~(1<<1);
        i=1;
        _delay_ms(200);

        if(++track>=7)            //если последний, то начать заново
        {
            track=0;
        }
    }
    //void Loading_melody()
    //{
    //      i=1;
    //      while(playlist[track][i]!=1)
    //      {
    //      playlist[track][i+1]=playlist[track][i+1]/(playlist[track][0]/60.000);
    //          // playlist[track][i+1]=pgm_read_word(playlist[track][i+1])/(pgm_read_word(playlist[track][0])/60.000);
    //      i++;
    //          if(playlist[track][i]!=1)
    //          {
    //          i++;
    //          }
    //      }
    //      i=1;
    //}

    int main(void)
    {

    PORTC=0x00;
    DDRC=0b000000011;

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: 8000,000 kHz
    // Mode: CTC top=OCR1A
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer 1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: On
    // Compare B Match Interrupt: Off
    //TCCR1A=0x00;
    //TCCR1B=0x09;
    TCCR1B |=1<<WGM12 | 1<<CS10;
    //TCNT1H=0x00;
    //TCNT1L=0x00;
    //ICR1H=0x00;
    //ICR1L=0x00;
    //OCR1AH=0x00;
    OCR1AL=0xFB;
    //OCR1BH=0x00;
    //OCR1BL=0x00;

    // Timer/Counter 2 initialization
    ASSR=0x00;
    TCCR2|= 1 << WGM20 | 1 << WGM21;  // Fast PWM mode
    TCCR2|= 1 << CS22;                // clk/256 - делим основную частоту МК на 256 (предделидель для таймера)
    TCNT2=0x00;
    OCR2=0x00;

    //TIMSK=0x10;
    TIMSK |= 1<<TOIE2 | 1<<OCIE1A; // разрешаем прерываемя по совпадению А от теймера/счетчика Т1
    sei();

        while (1)
        {

            while (pgm_read_word(&(playlist[track][i])) != 1)      //читаем данные с массива мелодии до тех пор
            {                                                                                        //пока не увидим признак окончания мелодии

                Bit = pgm_read_word(&(playlist[track][i]));                  //считываю ноту
                NoteLong = pgm_read_word(&(playlist[track][i+1]));  //считываю длительность ноты

                if (Bit == 0)
                {
                    pause();
                }
                else
                {
                    play();
                }
            }

            stop();
        }
    }
     
     
  10. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,160
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE
    Probably by hand... You can download music scores from the web... Then put them into the array's manually..
     
  11. wkrug

    wkrug Active Member

    Joined:
    May 30, 2010
    Messages:
    271
    Likes:
    29
    Location:
    Germany
    FreshMan
    Do You wanna play Notes or complete Samples?
    When using Samples you should make a .wav File. The Sample Rate should bes as high than the later PWM frequency.
    From that wav File you can create a .c file with a tool.
    Than you should give the values of the .c file into the Comparematch Register of the uses Timer in an Timer Overflow Interrupt.
    So the Timer give out the PWM Samples of your wished File.
    Add an Low Pass Filter and an Audio Amplfier behind this and the Sound will be given out.

    Code (text):
    #include <mega32.h>
    #include <delay.h>
    #include "data.c"
    //#include "data1.c"
    //#include "data2.c"

    #define flashport PORTB.0

    //Pointer für die PWM Soundtabelle
    volatile unsigned int ui_soundpointer=0;
    //Interruptzähler um eine Abtastrate von 15625 bei 8MHz zu erhalten
    volatile unsigned char uc_intcounter=0;
    ...

    ...
    / Timer 0 overflow interrupt service routine
    interrupt [TIM0_OVF] void timer0_ovf_isr(void)
    {
    uc_intcounter++;
    if (uc_intcounter>2)                            //Bei jedem 2ten Durchlauf wird der nächste Wert verwendet
        {
        uc_intcounter=0;
        OCR0=Jakobsleiter8s_wav[ui_soundpointer];    //Tabelle auslesen und ins Comparematch- register tun
        ui_soundpointer++;
        if(ui_soundpointer>Jakobsleiter8s_wav_len)  //Ende der Tabelle feststellen
            {
            ui_soundpointer=0;
            }
        }

    }

    // Declare your global variables here

    void main(void)
    {
    // Declare your local variables here

    // Input/Output Ports initialization
    // Port A initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTA=0x00;
    DDRA=0x00;

    // Port B initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=0 State2=T State1=T State0=T
    PORTB=0x00;
    DDRB=0x09;

    // Port C initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTC=0x00;
    DDRC=0x00;

    // Port D initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTD=0x00;
    DDRD=0x00;

    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: 16000,000 kHz
    // Mode: Fast PWM top=FFh
    // OC0 output: Non-Inverted PWM
    TCCR0=0x69;
    TCNT0=0x00;
    OCR0=0x80;

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: Timer 1 Stopped
    // Mode: Normal top=FFFFh
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer 1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: Off
    // Compare B Match Interrupt: Off
    TCCR1A=0x00;
    TCCR1B=0x00;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;

    // Timer/Counter 2 initialization
    // Clock source: System Clock
    // Clock value: Timer 2 Stopped
    // Mode: Normal top=FFh
    // OC2 output: Disconnected
    ASSR=0x00;
    TCCR2=0x00;
    TCNT2=0x00;
    OCR2=0x00;

    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    // INT2: Off
    MCUCR=0x00;
    MCUCSR=0x00;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x01;

    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    SFIOR=0x00;

    // Global enable interrupts
    #asm("sei")

    while (1)
          {
          //Thats only for a flashing light. The Soud Generation is in the Timer Interrupt Routine
          //Blitzen wird nachgebildet
          flashport=1;
          delay_ms(uc_lighttable[uc_sparkpointer]);
          flashport=0;
          delay_ms(uc_pausetable[uc_sparkpointer]);
          uc_sparkpointer++;
       
          };
     
    Now a litte snippet from the Table

    Code (text):
    flash unsigned char Jakobsleiter8s_wav[] = {
      0x8c, 0x81, 0x87, 0x87, 0x84, 0x84, 0x82, 0x7a, 0x7a, 0x89, 0x6f, 0x92,
      0x8c, 0x73, 0x7d, 0x84, 0x8d, 0x7d, 0x77, 0x78, 0x8a, 0x7f, 0x91,
    ...

    ...
    0x63, 0x70, 0x72
    };
    #define Jakobsleiter8s_wav_len 20727
    At a sample rate of 8000 Bytes per second you have 1 Second Play Time for the whole Flash of the ATMEGA 8

    When You want to take Ringtone Files you have to programm a Parser, that rad out such one file and convert it in tones.
    To Do that you must know, how the Ringtonefile ist structured.
    In an older Elektor there was an articel about this.

    !EDIT:
    The tool i used to convert .wav into .c files is called vim
     
    Last edited: Oct 23, 2013
  12. FreshMan

    FreshMan New Member

    Joined:
    Oct 21, 2013
    Messages:
    7
    Likes:
    0
    Location:
    Ukraine
    I wanna play Notes :)
    maybe, you you give a hint on how to make it easier ?;)
     
  13. FreshMan

    FreshMan New Member

    Joined:
    Oct 21, 2013
    Messages:
    7
    Likes:
    0
    Location:
    Ukraine
    so does anyone know how to play notes ?
     
  14. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,160
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE
    The simple way is to look at the frequency of each note and to blit it out a single pin... Or implement the PWM shown in previous posts..
     
  15. FreshMan

    FreshMan New Member

    Joined:
    Oct 21, 2013
    Messages:
    7
    Likes:
    0
    Location:
    Ukraine
    in principle, I found a project where it is implemented http://aquaticus.info/pwm-music , this is what I need
    but one problem remains unsolved
    I don't know how to translate the notes in the array
    musical education I don't have
    can anyone tell how to do this easily or point to a program that does it ?
     
  16. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,160
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE
    The array... contains the note..
    Look at the table...

    C4 ( middle C ) = 261.63 hz = time 3822 uS if you load the ICR you need to divide by 2 ie.. 1922

    Lets take a melody... Amazing grace.. http://www.onlinesheetmusic.com/amazing-grace-my-chains-are-gone-p395813.aspx

    You can copy the notes / duration etc... and use that in the array The score tells you everything you need to know.

    There are FREE ringtone downloads every where on the net that will send the note arrays to your phone...
     
  17. FreshMan

    FreshMan New Member

    Joined:
    Oct 21, 2013
    Messages:
    7
    Likes:
    0
    Location:
    Ukraine
    I understand this :)
    I can't understand only one: if I look at that kind of music notation http://ic.pics.livejournal.com/antplat/13715091/317611/317611_original.jpg I can't understand where there C4, B4, G4, F4
    please, help
     
  18. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,160
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE
    Just google... http://www.wikihow.com/Read-Music Al you need to know... Just use it as a reference..

    There are online music creators so you can test your sounds... I use Fast tracker 2 to write scores... I also have NWC
    NoteWortyComposer.. I also have sound booth ( Used to be Cool Edit Pro ) until Adobe bought it out...

    If you are serious you need to get one
     

Share This Page