Jump to content
ELFORUM - Forumul Electronistilor
Sign in to follow this  
Lilith

Note muzicale

Recommended Posts

Buna ziua, as dori sa realizez o sonerie care sa cante cateva note muzicale cu un PIC, imi puteti spune cum as putea incepe si ce componente as avea nevoie? (am mai lucrat cu mplab)

Share this post


Link to post
Share on other sites

Salut. Note muzicale simple gen cum erau mai de mult cutiutele muzicale de la instalatiile de la bradul de craciun se pot obtine relativ simplu cu PIC, pentru ceva mai complex un modul DFPlayer si card de memorie cu fisiere .mp3

 

Pentru PIC eu am folosit un PIC cu modul NCO care poate genera semnal PWM cu umplere de 50% cu frecventa variabila care poate fi setat destul de precis, mult peste PWM simplu. NCO-ul are ca intrare setat LFINTOSC care este de 31khz pentru cu notele muzicale sunt de frecventa redusa pana in maxim 2khz. De acolo e nevoie doar de multa rabdare pana calculezi valorile necesare pt NCO pt fiecare nota muzicala in parte si sa scrii un sir de note muzicale. Ca exemplu  Nota_x, durata, durataPauza. 

 

Daca esti interesat o sa caut codul sursa si il postez. 

Edited by Bandi Szasz

Share this post


Link to post
Share on other sites
La 26.11.2019 la 17:46, Lilith a spus:

Buna ziua, as dori sa realizez o sonerie care sa cante cateva note muzicale cu un PIC, imi puteti spune cum as putea incepe si ce componente as avea nevoie? (am mai lucrat cu mplab)

 

Cu respect, va complicati inutil si costisitor, sunt foarte multe jucării cu melodii si alte sunete, gen, gingle, utilitare, SF, etc...

Share this post


Link to post
Share on other sites
1 oră în urmă, alcon a spus:

 

Cu respect, va complicati inutil si costisitor, sunt foarte multe jucării cu melodii si alte sunete, gen, gingle, utilitare, SF, etc...

Poate ca nu... mie mi s-a cerut o data sa fac o sonerie cu "M-a facut mama oltean"... vorbesc serios! :) 

 

L.E. Am gasit si schema intr-un dosar din "copilarie"... cre` ca are 25 - 30 ani ca nimica... :rade:

 

iBzCYnX.jpg

Edited by informer

Share this post


Link to post
Share on other sites

Eu nu prea am lucrat cu PIC, dar pentru AVR (sau Arduino) sunt deja mai multe librarii pentru sunete, 

cea de la arduino se cheama tone daca nu ma insel, eu am utilizat-o ca sa fac niste sonerii de alarma mai interesante.

La Arduino tone() nu iti blocheaza executia normala a programului.

 

Sigur si pentru PIC exista ceva.

In MikroC for PIC gasesti libraria sound. Am impresia ca executia programului se opreste pentru reproducerea sunetelor dar daca acesta este scopul principal nu cred ca e o problema.

 

Uite aici un exemplu.

 

Daca cunosti PIC-urile suficient cred ca poti sa iti faci singur propria librarie, bazata pe intreruperi, astfel nu afectezi executia programului.

 

Daca vrei sa obtii ceva mai special, fara a folosi semnalele dreptunghiulare de la micro pentru sunet, poti cumpara un "xilofon" si adapta niste actuatoare care sa loveasca placutele, astfel obtii sunete mult mai naturale.

 

Cauta pe youtube Arduino Glockenspiel

 

 

 

Edited by one

Share this post


Link to post
Share on other sites

Spre exemplu daca as dori sa reproduc nota LA care are frecventa de 440hz, asa zic ca ar arata codul:

#include p16f877.inc

i equ 0x20

j equ 0x21

 

main: BSF STATUS, RP0

           MOVLW B'10111111'

           MOVWF TRISB

           BCF STATUS,RP0

           MOVLW D'220'

           MOVWF i

loopla:BSF PORTB,6

            CALL delay_1135us

             BCF PORTB,6

             CALL delay_1135us

             DECFSZ i,1

             GOTO loopla

             NOP

delay_1135us:MOVLW D'227'

                          MOVWF

loop:NOP

         NOP

         DECFSZ j,1

         GOTO loop

         RETURN

         end

si in c:

#include <htc.h>

#define_XTAL_FREQ 4000000

 

void main(void)

{

unsigned char i;

TRISB=0;

for(i=220;i>0;i--)

{  RB6=1;

    __delay_us(1135);

RB6=0;

__delay_us(1135);

}

Ce completari ar fi necesare pentru a putea reproduce cel putin inca 4 note muzicale diferite ? Si inafara de mplab cum as putea verifica daca codul e bun de implementat in hard ?

Share this post


Link to post
Share on other sites

Compilatoarele MikroElectronica ( c, pascal, basic) au o librarie foarte usor de folosit si este si un exemplu de la care se poate pleca.

Share this post


Link to post
Share on other sites

Din pacate nu ma pricep la formatul de cod pe care l-ai postat, eu lucrez in MikroC. Implementarea mea este bazata pe module hardware fara nici un delay pentru ca PIC-ul pe langa sunet are si alte atributii care necesita temporizari foarte precise la nivel de nanosecunde, era exclus sa folosesc delay sau libraria inclusa in mikroC care este blocanta. 

 

Implementarea este cam in felul urmator.  Modulul PWM generateaza un semnal dreptunghiular cu umplere 50% de 20uS, semnalul PWM este trecut prin modulul CLC pentru ca modulul NCO permite utilizarea iesirii modulului CLC in loc de frecventa oscilatorului care este prea mare ca sa poata genera frecvente mici de 300hz cu precizie pentru ca intre Nota E4 si F4 diferenta este doar de 20Hz. Pentru fiecare nota am calculat valoarea necesara pentru modulul NCO sa genereze frecventa fiecarei note in parte si valori pentru Timer 1 care e folosit pentru durata notelor in loc de delay care este blocanta.

 

Picul folosit este PIC16F18326

 

Cam asta ar fi setarile

#include "song_data.h"

unsigned int notePosition = 0;

void TMR1_Init(void){
  T1GCON = 0x00;
  T1CON = 0xC0; // LFINTOSC 1:1
  PIR1.TMR1IF = 0; // interrupt flag
  PIE1.TMR1IE = 1; // enable interrupt
}

void TMR1_Start() {
  TMR1H = 0xFF;
  TMR1L = 0xE1;
  T1CON.TMR1ON = 1;
}

void TMR1_Stop() {
 T1CON.TMR1ON = 0;
}

void Sound_Init() {
  TMR1_Init();

  // 20uS
  T6CON = 0x04;
  PR6 = 159;

  // PWM5 on TMR6
  PWM5CON = 0xA0;
  PWM5DCH = 79;
  PWM5DCL = 0;
  
  // PWM 5 through CLC1
  CLC1POL = 0x8E;
  CLC1SEL0 = 0x10;
  CLC1SEL1 = 0x00;
  CLC1SEL2 = 0x00;
  CLC1SEL3 = 0x00;
  CLC1GLS0 = 0x02;
  CLC1GLS1 = 0x00;
  CLC1GLS2 = 0x00;
  CLC1GLS3 = 0x00;
  CLC1CON = 0x82;

  // NCO as 50% PWM with variable frequency, clock source CLC1
  NCO1CON = 0xE0;
  NCO1CLK = 0x02;
  NCO1CON.F7 = 0;
  NCO1INCH = 0x30;
  NCO1INCL = 0x16;
  
  // NCO output on pin RC4 using PPS
  Unlock_IOLOCK();
  RC4PPS = 0x1D;
  Lock_IOLOCK();
}

void delay(int time) {
int i;
  for (i=0; i<time; i++) {
    delay_ms(1);
  }
}

void playSong(char track) {
  switch(track) {
    case 1:
      notePosition = 0;
      break;
    case 2:
      //*currentTrack = &WeWishYouAMerr[0];
      break;
    case 3:
      //*currentTrack = &RudolfTheRedNosed[0];
      break;
    case 4:
      //*currentTrack = &JingleBells[0];
      break;
  };

  TMR1_Start();
}

// TMR1 interrupt
void ISR_Sound() {
  if (NCO1CON.F7) { // pause before next tone
    NCO1CON.F7 = 0;
    TMR1H = melodyList[notePosition] >> 8;
    TMR1L = melodyList[notePosition++] & 0xFF;
    
    // End of track, stop Timer1
    if (melodyList[notePosition] == 0xFFFF) {
      TMR1_Stop();
    }
    
  } else { // next tone
    NCO1INCH = melodyList[notePosition] >> 8;
    NCO1INCL = melodyList[notePosition++] & 0xff;
    TMR1H = melodyList[notePosition] >> 8;
    TMR1L = melodyList[notePosition++] & 0xFF;
    NCO1CON.F7 = 1;
  }
}

 

 

Si asa ar arata o melodie definita

#define tone_D5 12310 //587
#define tone_C5D5 11618 //554
#define tone_B4 10357 //493.88
#define tone_A4 9227 //440
#define tone_G4 8220 //392
#define tone_F4G4 7759 //369.99
#define tone_E4 6912 //329.63
#define tone_D4 6158 //293.66
#define tone_D4E4 6524 // 311.13
#define tone_G4A4 8709 // 415.30
#define tone_A4B4 9776 // 466.16
#define tone_F4 7323 // 349.23
#define tone_C5 10973 // 523.25
#define tone_D5E5 13049 // 622.25
#define tone_G5 16441 // 783.99


// 31/ms  total: 65535

#define time_450 51585
#define time_337 55088
#define time_112 62063
#define time_675 44610
#define time_225 58560
#define time_670 44765
#define time_220 58715


#define time_80 63055
#define time_50 63985
#define time_38 64357
#define time_13 65132
#define time_75 63210
#define time_25 64760
#define time_30 64605
#define time_20 64915
#define time_125 61660

unsigned int melodyList[] = {

// ## JoyToTheWorld ##
tone_D5, time_450, time_50,
tone_C5D5, time_337, time_38,
tone_B4, time_112, time_13,
tone_A4, time_675, time_75,
tone_G4, time_225, time_25,
tone_F4G4, time_450, time_50,
tone_E4, time_450, time_50,
tone_D4, time_675, time_75,
tone_A4, time_225, time_25,
tone_B4, time_670, time_80,
tone_B4, time_225, time_25,
tone_C5D5, time_670, time_80,
tone_C5D5, time_225, time_25,
tone_D5, time_670, time_80,
tone_D5, time_220, time_30,
tone_D5, time_225, time_25,
tone_C5D5, time_225, time_25,
tone_B4, time_225, time_25,
tone_A4, time_220, time_38,
tone_A4, time_337, time_38,
tone_G4, time_112, time_13,
tone_F4G4, time_225, time_25,
tone_D5, time_220, time_30,
tone_D5, time_225, time_20,
tone_C5D5, time_225, time_25,
tone_B4, time_225, time_20,
tone_A4, time_220, time_30,
tone_A4, time_337, time_38,
tone_G4, time_112, time_13,
tone_F4G4, time_220, time_30,
tone_F4G4, time_220, time_30,
tone_F4G4, time_220, time_30,
tone_F4G4, time_220, time_30,
tone_F4G4, time_220, time_30,
tone_F4G4, time_112, time_13,
tone_G4, time_112, time_13,
tone_A4, time_675, time_75,
tone_G4, time_112, time_125,
tone_F4G4, time_112, time_13,
tone_E4, time_220, time_30,
tone_E4, time_220, time_30,
tone_E4, time_220, time_30,
tone_E4, time_112, time_125,
tone_F4G4, time_112, time_13,
tone_G4, time_675, time_75,
tone_F4G4, time_112, time_13,
tone_E4, time_112, time_13,
tone_D4, time_225, time_25,
tone_D5, time_450, time_50,
tone_B4, time_225, time_25,
tone_A4, time_337, time_38,
tone_G4, time_112, time_13,
tone_F4G4, time_225, time_25,
tone_G4, time_225, time_25,
tone_F4G4, time_450, time_50,
tone_E4, time_450, time_50,
0xFFFF
};

 

 

O varianta mult mai simpla ar fi folosirea directa a PWM-ului pentru a genera notele insa precizia frecventei nu poate fi controlata atat de precis ca si cu NCO si in loc de TMR1 se pot folosii delay-uri daca PIC-ul nu are si alte treburi de facut.

Edited by Bandi Szasz
Informatii suplimentare

Share this post


Link to post
Share on other sites

Daca e un prototip unic si nu o constructie in serie, daca nu este timp de experimente, daca trebuiesc respectate temporizari, se poate considera si utilizarea a 2 micro, unul pentru melodie si unul pentru celelalte functii.

Eu am utilizat aceasta solutie in trecut, chiar daca se putea face totul cu un singur controller. Am utilizat un controller pentru comunicatie, interfete display-tastatura, unde am folosit librarii deja facute de altii, iar pentru controlul unui proces am utilizat alt controller, programat direct cu assembler, astfel aveam controlul complet al timpilor de executie si un eventual debug era mai simplu de facut.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.