Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
SITAEL_Sound-Generation.cpp
00001 // Tested : NUCLEO F207ZG 00002 // Tested : NUCLEO L476RG 00003 #include "mbed.h" 00004 00005 // Definizione periferiche 00006 Serial pc(USBTX, USBRX); 00007 //AnalogOut OutWave(PA_5); //F207ZG 00008 AnalogOut OutWave(PA_4); //L476RG 00009 DigitalOut DigitalWave(PA_1); 00010 DigitalOut led1(LED1); 00011 DigitalOut led2(LED2); 00012 DigitalOut led3(LED3); 00013 00014 // definizione della frequenza delle note ottava centrale del pianoforte 00015 #define Z 100.00 // diagnostica 00016 #define C 261.63 00017 #define Cd 277.18 00018 #define Db 277.18 00019 #define D 293.66 00020 #define Dd 311.13 00021 #define Eb 311.13 00022 #define E 329.63 00023 #define F 349.23 00024 #define Fd 369.99 00025 #define Gb 369.99 00026 #define G 392.9 00027 #define Gd 415.3 00028 #define Ab 415.3 00029 #define A 440.0 00030 #define Ad 466.16 00031 #define Bb 466.16 00032 #define B 493.18 00033 00034 00035 00036 00037 00038 00039 // numero di campioni che compongono un periodo della sinusoide in Output sull'ADC 00040 #define SAMPLESINENUM 45// consigliabile avere multipli di 45 00041 00042 // parametri dell'onda coseno da generare 00043 #define PI (3.141592653589793238462) 00044 #define AMPLITUDE 32767 //(1.0) // x * 3.3V 00045 #define PHASE (PI/2) // 2*pi è un periodo 00046 #define OFFSET 32767 //(0x7FFF) 00047 00048 // numero di note componenti la scala diatonica 00049 #define NUMTONE 120 00050 00051 // Output LED di diagnostica 00052 DigitalOut led(LED1); 00053 00054 // ticker per la generazione dell'onda con DAC 00055 Ticker SampleOutTicker; 00056 00057 // Buffer contenente la sinusoide da porre in output. 00058 unsigned short usaSine[SAMPLESINENUM]; 00059 00060 // prototipo di funzione che genera i campioni della sinusoide da utilizzare per la generazione tramite DAC 00061 void CalculateSinewave(void); 00062 00063 // carattere in arrivo dal PC 00064 volatile char cReadChar=0; 00065 volatile char cOldReadChar=0; 00066 00067 // indice, nell'array, del campione da porre in output 00068 volatile int nSampleOutIndex; 00069 // contatore dei campioni in output sul DAC 00070 volatile int nSampleOutCount; 00071 // Periodo di generazione campioni in output DeltaT = T/NumSample 00072 double fDeltaT; 00073 // amplificazione per il dato da spedire sull'ADC 00074 volatile double fAmp; 00075 //volatile double fAmpNew; 00076 // flag per bloccare la generazione del segnale 00077 volatile bool bStop; 00078 // frequenza segnale da generare 00079 volatile double fFreq; 00080 // periodo della sinusoide da generare 00081 double fPeriod; 00082 double dDiatonic[NUMTONE]; 00083 00084 //**************************** 00085 // Create the sinewave buffer 00086 //**************************** 00087 void CalculateSinewave(int nOffset, int nAmplitude, double fPhase) 00088 { 00089 // variabile contenente l'angolo in radianti 00090 double fRads; 00091 // indici per i cicli 00092 int nIndex; 00093 // passo in frequenza fissato dal numero di campioni in cui voglio dividere un periodo di sinusoide: DeltaF = 360°/NUMSAMPLE 00094 double fDeltaF; 00095 // angolo per il quale bisogna calcolare il valore di sinusoide: fAngle = nIndex*DeltaF 00096 double fAngle; 00097 00098 fDeltaF = 360.0/SAMPLESINENUM; 00099 for (nIndex = 0; nIndex < SAMPLESINENUM; nIndex++) 00100 { 00101 fAngle = nIndex*fDeltaF; // angolo per il quale bisogna calcolare il campione di sinusoide 00102 fRads = (PI * fAngle)/180.0; // Convert degree in radian 00103 //usaSine[nIndex] = AMPLITUDE * cos(fRads + PHASE) + OFFSET; 00104 usaSine[nIndex] = nAmplitude * cos(fRads + fPhase) + nOffset; 00105 } 00106 } 00107 00108 00109 //********************************************** 00110 // Crea le frequenze delle note del pianoforte 00111 //********************************************** 00112 void CreateDiatonic() 00113 { 00114 int nTono; 00115 int nOttava; 00116 00117 // ottava centrale = ottava 4 00118 dDiatonic[4*12+0]=261.63; // C 00119 dDiatonic[4*12+1]=277.18; // C#/Db 00120 dDiatonic[4*12+2]=293.66; // D 00121 dDiatonic[4*12+3]=311.13; // D#/Eb 00122 dDiatonic[4*12+4]=329.63; // E 00123 dDiatonic[4*12+5]=349.23; // F 00124 dDiatonic[4*12+6]=369.99; // F#/Gb 00125 dDiatonic[4*12+7]=392.00; // G 00126 dDiatonic[4*12+8]=415.30; // G#/Ab 00127 dDiatonic[4*12+9]=440.00; // A 00128 dDiatonic[4*12+10]=466.16; // A#/Bb 00129 dDiatonic[4*12+11]=493.88; // B 00130 00131 // dalla ottava 5 alla 9 00132 for(nOttava=5; nOttava<9; nOttava++) 00133 { 00134 for(nTono=0; nTono<12; nTono++) 00135 { 00136 dDiatonic[(nOttava*12)+nTono]=dDiatonic[((nOttava-1)*12)+nTono]*2; 00137 } 00138 } 00139 00140 // dalla ottava 0 alla 3 00141 for(nOttava=3; nOttava>=0; nOttava--) 00142 { 00143 for(nTono=0; nTono<12; nTono++) 00144 { 00145 dDiatonic[(nOttava*12)+nTono]=dDiatonic[((nOttava+1)*12)+nTono]/2; 00146 } 00147 } 00148 } 00149 00150 //*************************** 00151 // generazione sample da DAC 00152 //*************************** 00153 void SampleOut() 00154 { 00155 // se è stato inviato il comando Stop, non fare niente fino a nuovo comando 00156 if(bStop) 00157 { 00158 } 00159 else // se non è stato inviato il comando di bStop continua 00160 { 00161 // output del campione della forma d'onda 00162 OutWave.write_u16(usaSine[nSampleOutIndex]); 00163 00164 // incrementa l'indice del campione in output, modulo NUMSAMPLE: se NUMSAMPLE è 360, nSampleOutIndex va da 0 a 359 00165 nSampleOutIndex++; 00166 if(nSampleOutIndex >= SAMPLESINENUM) 00167 { 00168 nSampleOutIndex=0; 00169 } 00170 00171 } 00172 } 00173 00174 00175 00176 00177 //******************* 00178 // Loop Principale 00179 //******************* 00180 int main() 00181 { 00182 // configura velocità della comunicazione seriale su USB-VirtualCom e invia messaggio di benvenuto 00183 pc.baud(921600); //921600 bps 00184 00185 00186 // messaggio di benvenuto 00187 pc.printf("\r\nHallo \r\n"); 00188 pc.printf("\r\n*** SineWave Generation ***\r\n"); 00189 00190 //inizializza variabili 00191 cReadChar = 0; 00192 nSampleOutIndex=0; 00193 nSampleOutCount=0; 00194 bStop=true; 00195 00196 // test dei LED 00197 led1=1; //Verde 00198 wait_ms(1000); 00199 led1=0; 00200 led2=1; // Blu 00201 wait_ms(1000); 00202 led2=0; 00203 led3=1; //Rosso 00204 wait_ms(1000); 00205 led3=0; 00206 //+++++++++++++++++++++++++++++++++++ START Test ONDA DIGITALE ++++++++++++++++++++++++++++++++++++++ 00207 /* 00208 led1=1; 00209 led2=1; 00210 led3=1; 00211 while(true) 00212 { 00213 DigitalWave=0; 00214 //wait_us(2024); //SI 00215 //wait_us(2551); //SOL 00216 wait_ms(300); //MI 00217 DigitalWave=1; 00218 wait_ms(300); 00219 } 00220 */ 00221 //+++++++++++++++++++++++++++++++++++ END Test ONDA DIGITALE +++++++++++++++++++++++++++++++++++++++++++++ 00222 00223 00224 //+++++++++++++++++++++++++++++++++++ START Test ONDA ANALOGICA ++++++++++++++++++++++++++++++++++++++++++ 00225 fFreq=20.0; // frequenza della sinusoide di test 00226 pc.printf("\n\r--- Generazione LA = %.2f Hz ampiezza nominale ---\n\r", fFreq); 00227 bStop = false; 00228 // genera la frequenza relativa alla nota che è stata selezionata 00229 fAmp = 0.3; // coefficiente per il quale viene moltiplicato l'ampiezza massima 00230 fDeltaT = 1.0/(fFreq*SAMPLESINENUM); 00231 CalculateSinewave(32767, (32767*fAmp), (PI/2.0)); // generazione della sinusoide con valori nominali 00232 SampleOutTicker.attach(&SampleOut,fDeltaT); // avvia output della sinusoide per generazione 00233 while(true){}; 00234 //+++++++++++++++++++++++++++++++++++ END Test ONDA ANALOGICA ++++++++++++++++++++++++++++++++++++++++++++ 00235 00236 //+++++++++++++++++++++++++++++++++++ START Test ONDA ANALOGICA ++++++++++++++++++++++++++++++++++++++++++++++ 00237 00238 // variabile contenente l'angolo in radianti 00239 double fRads; 00240 // passo in frequenza fissato dal numero di campioni in cui voglio dividere un periodo di sinusoide: DeltaF = 360°/NUMSAMPLE 00241 double fDeltaF; 00242 // angolo per il quale bisogna calcolare il valore di sinusoide: fAngle = nIndex*DeltaF 00243 double fAngle; 00244 00245 fFreq=10.0;// frequenza della sinusoide DO da generare 00246 pc.printf("\n\r--- Generazione frequenza = %.2f Hz ---\n\r", fFreq); 00247 00248 00249 nSampleOutIndex=0; 00250 while(true) 00251 { 00252 00253 // output del campione della forma d'onda 00254 //OutWave.write_u16( 32767*cos(nSampleOutIndex/3.14)); 00255 OutWave.write_u16( nSampleOutIndex); 00256 00257 // incrementa l'indice del campione in output, modulo NUMSAMPLE: se NUMSAMPLE è 360, nSampleOutIndex va da 0 a 359 00258 nSampleOutIndex++; 00259 if(nSampleOutIndex >= 32768) 00260 { 00261 nSampleOutIndex =0; 00262 } 00263 00264 wait_ms(10); 00265 } 00266 00267 //+++++++++++++++++++++++++++++++++++ END Test ONDA ANALOGICA ++++++++++++++++++++++++++++++++++++++++++ 00268 00269 //+++++++++++++++++++++++++++++++++++ START Loop principale ++++++++++++++++++++++++++++++++++++++++++ 00270 while(true) 00271 { 00272 // verifica se è arrivato un carattere dalla seriale del pc 00273 if(pc.readable()) 00274 //if (true) 00275 { 00276 cReadChar = pc.getc(); // Read hyperterminal 00277 //cReadChar = 'C'; 00278 // genera la nota corrispondente al carattere ricevuto 00279 switch(cReadChar) 00280 { 00281 //DO 00282 case 'c': 00283 case 'C': 00284 { 00285 fFreq=261.63;// frequenza della sinusoide DO da generare 00286 pc.printf("\n\r--- Generazione DO = %.2f Hz ampiezza nominale ---\n\r", fFreq); 00287 bStop = false; 00288 } break; 00289 // RE 00290 case 'd': 00291 case 'D': 00292 { 00293 fFreq=293.66;// frequenza della sinusoide RE da generare 00294 pc.printf("\n\r--- Generazione RE = %.2f Hz ampiezza nominale ---\n\r", fFreq); 00295 bStop = false; 00296 } break; 00297 // RE#/MIb 00298 case 'm': 00299 case 'M': 00300 { 00301 fFreq=311.13; 00302 pc.printf("\n\r--- Generazione Mib = %.2f Hz ampiezza nominale ---\n\r", fFreq); 00303 bStop = false; 00304 } break; 00305 case 'e': 00306 case 'E': 00307 { 00308 fFreq=329.63; // frequenza della sinusoide MI da generare 00309 pc.printf("\n\r--- Generazione MI = %.2f Hz ampiezza nominale ---\n\r", fFreq); 00310 bStop = false; 00311 } break; 00312 case 'f': 00313 case 'F': 00314 { 00315 fFreq=349.23;// frequenza della sinusoide FA da generare 00316 pc.printf("\n\r--- Generazione FA = %.2f Hz ampiezza nominale ---\n\r", fFreq); 00317 bStop = false; 00318 } break; 00319 00320 // SOL 00321 case 'g': 00322 case 'G': 00323 { 00324 fFreq=392.0; 00325 pc.printf("\n\r--- Generazione SOL = %.2f Hz ampiezza nominale ---\n\r", fFreq); 00326 bStop = false; 00327 } break; 00328 // LA 00329 case 'a': 00330 case 'A': 00331 { 00332 fFreq=440.0; // frequenza della sinusoide LA da generare 00333 pc.printf("\n\r--- Generazione LA = %.2f Hz ampiezza nominale ---\n\r", fFreq); 00334 bStop = false; 00335 } break; 00336 //SI 00337 case 'b': 00338 case 'B': 00339 { 00340 fFreq=493.88;// frequenza della sinusoide SI da generare 00341 pc.printf("\n\r--- Generazione SI = %.2f Hz ampiezza nominale ---\n\r", fFreq); 00342 bStop = false; 00343 } break; 00344 00345 // pausa 00346 case ' ': 00347 { 00348 bStop=true; 00349 pc.printf("\n\r--- Generation Stopped ---\n\r"); 00350 } break; 00351 default: 00352 { 00353 bStop=true; // se la nota non è riconosciuta blocca la generazione 00354 pc.printf("\n\r--- Wrong Tone ---\n\r"); 00355 } break; 00356 } // switch (cReadChar) 00357 00358 // genera la frequenza relativa alla nota che è stata selezionata 00359 fAmp = 1.0; // coefficiente per il quale viene moltiplicato l'ampiezza massima 00360 fDeltaT = 1.0/(fFreq*SAMPLESINENUM); 00361 CalculateSinewave(32767, (32767*fAmp), (PI/2.0)); // generazione della sinusoide con valori nominali 00362 SampleOutTicker.attach(&SampleOut,fDeltaT); // avvia output della sinusoide per generazione 00363 } 00364 else // se non è stato premuto nessun tasto diagnostica 00365 { 00366 00367 } 00368 } 00369 00370 00371 }
Generated on Wed Aug 31 2022 14:01:53 by
1.7.2