Amaldi / Mbed 2 deprecated Amaldi_14_Exercise_ProxSensor

Dependencies:   mbed

Committer:
pinofal
Date:
Tue Nov 20 11:13:44 2018 +0000
Revision:
8:4dfa352455c4
Proximity UltrasoundSensor + Clacson

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pinofal 8:4dfa352455c4 1 // Tested : NUCLEO F207ZG
pinofal 8:4dfa352455c4 2 //#include "SoundSample.h"
pinofal 8:4dfa352455c4 3 #include "mbed.h"
pinofal 8:4dfa352455c4 4 #include<stdlib.h>
pinofal 8:4dfa352455c4 5
pinofal 8:4dfa352455c4 6
pinofal 8:4dfa352455c4 7
pinofal 8:4dfa352455c4 8 // numero di campioni che compongono un periodo della sinusoide in Output sull'ADC
pinofal 8:4dfa352455c4 9 #define SAMPLESINENUM 45 // consigliabile avere multipli di 45
pinofal 8:4dfa352455c4 10
pinofal 8:4dfa352455c4 11 // parametri dell'onda coseno da generare
pinofal 8:4dfa352455c4 12 #define PI (3.141592653589793238462)
pinofal 8:4dfa352455c4 13 #define AMPLITUDE 32767 //(1.0) // x * 3.3V
pinofal 8:4dfa352455c4 14 #define PHASE (PI/2) // 2*pi è un periodo
pinofal 8:4dfa352455c4 15 #define OFFSET 32767 //(0x7FFF)
pinofal 8:4dfa352455c4 16
pinofal 8:4dfa352455c4 17 // numero di note componenti la scala diatonica della marimba
pinofal 8:4dfa352455c4 18 #define NUMTONE 120
pinofal 8:4dfa352455c4 19
pinofal 8:4dfa352455c4 20 // Definizione periferiche
pinofal 8:4dfa352455c4 21 Serial pc(USBTX, USBRX);
pinofal 8:4dfa352455c4 22 AnalogOut OutWave(PA_4); // pin A2 di output per la forma d'onda analogica
pinofal 8:4dfa352455c4 23 DigitalOut OutPulse(PC_0);
pinofal 8:4dfa352455c4 24 DigitalIn myButton(USER_BUTTON); // User Button
pinofal 8:4dfa352455c4 25 //DigitalOut led1(LED1);
pinofal 8:4dfa352455c4 26 DigitalOut led2(LED2);
pinofal 8:4dfa352455c4 27 //DigitalOut led3(LED3);
pinofal 8:4dfa352455c4 28 DigitalInOut myProx (PC_0, PIN_OUTPUT, PullNone, 0);
pinofal 8:4dfa352455c4 29 Timer myTimer;
pinofal 8:4dfa352455c4 30
pinofal 8:4dfa352455c4 31 // ticker per la generazione dell'onda con DAC
pinofal 8:4dfa352455c4 32 Ticker SampleOutTicker;
pinofal 8:4dfa352455c4 33
pinofal 8:4dfa352455c4 34 // Buffer contenente la sinusoide da porre in output.
pinofal 8:4dfa352455c4 35 unsigned short usaSine[SAMPLESINENUM];
pinofal 8:4dfa352455c4 36
pinofal 8:4dfa352455c4 37 // prototipo di funzione che genera i campioni della sinusoide da utilizzare per la generazione tramite DAC
pinofal 8:4dfa352455c4 38 void CalculateSinewave(void);
pinofal 8:4dfa352455c4 39 // funzione di generazione suono della frequenza e ampiezza selezionate
pinofal 8:4dfa352455c4 40 void SoundGenerate(double fFrequency);
pinofal 8:4dfa352455c4 41
pinofal 8:4dfa352455c4 42 // carattere in arrivo dal PC
pinofal 8:4dfa352455c4 43 volatile char cReadChar;
pinofal 8:4dfa352455c4 44 volatile char CReadMusic;
pinofal 8:4dfa352455c4 45 // indice, nell'array, del campione da porre in output
pinofal 8:4dfa352455c4 46 //volatile int nSampleOutIndex;
pinofal 8:4dfa352455c4 47 // contatore dei campioni in output sul DAC
pinofal 8:4dfa352455c4 48 //volatile int nSampleOutCount;
pinofal 8:4dfa352455c4 49
pinofal 8:4dfa352455c4 50 // indice nell'array dei campioni da porre in output da DAC per Marimba
pinofal 8:4dfa352455c4 51 volatile int nSampleSoundIndex;
pinofal 8:4dfa352455c4 52
pinofal 8:4dfa352455c4 53 // Periodo di generazione campioni in output DeltaT = T/NumSample
pinofal 8:4dfa352455c4 54 double fDeltaT;
pinofal 8:4dfa352455c4 55 // amplificazione per il dato da spedire sull'ADC
pinofal 8:4dfa352455c4 56 volatile double fAmp;
pinofal 8:4dfa352455c4 57 //volatile double fAmpNew;
pinofal 8:4dfa352455c4 58 // flag per bloccare la generazione del segnale
pinofal 8:4dfa352455c4 59 volatile int bGenerate = false;
pinofal 8:4dfa352455c4 60 // flag per indicare se è richiesta la generazione del suono di marimba
pinofal 8:4dfa352455c4 61 volatile int bMarimba = false;
pinofal 8:4dfa352455c4 62 // frequenza segnale da generare
pinofal 8:4dfa352455c4 63 volatile double fFreq;
pinofal 8:4dfa352455c4 64 //flag che diventa true se bisogna fermare la generazione di suoni
pinofal 8:4dfa352455c4 65 volatile int bStop=true;
pinofal 8:4dfa352455c4 66 // periodo della sinusoide da generare
pinofal 8:4dfa352455c4 67 double fPeriod;
pinofal 8:4dfa352455c4 68 // tipo di suono da generare: 0=Sine, 1= Square
pinofal 8:4dfa352455c4 69 char cSoundWave;
pinofal 8:4dfa352455c4 70 // nota corrispondente al tasto premuto
pinofal 8:4dfa352455c4 71 volatile char cKeyToPlay= '\0';
pinofal 8:4dfa352455c4 72 // indice per i cicli
pinofal 8:4dfa352455c4 73 volatile int nIndex;
pinofal 8:4dfa352455c4 74
pinofal 8:4dfa352455c4 75 // numero di campioni presenti in 2 secondi
pinofal 8:4dfa352455c4 76 int nSampleCount;
pinofal 8:4dfa352455c4 77
pinofal 8:4dfa352455c4 78 // inizio e fine del timer che misura la distanza con il sensore ultrasuoni
pinofal 8:4dfa352455c4 79 int nTimerStart, nTimerStop;
pinofal 8:4dfa352455c4 80 // distanza in cm dell'ostacolo
pinofal 8:4dfa352455c4 81 double fDistance;
pinofal 8:4dfa352455c4 82
pinofal 8:4dfa352455c4 83 //****************************
pinofal 8:4dfa352455c4 84 // Create the sinewave buffer
pinofal 8:4dfa352455c4 85 //****************************
pinofal 8:4dfa352455c4 86 void CalculateSinewave(int nOffset, int nAmplitude, double fPhase)
pinofal 8:4dfa352455c4 87 {
pinofal 8:4dfa352455c4 88 // variabile contenente l'angolo in radianti
pinofal 8:4dfa352455c4 89 double fRads;
pinofal 8:4dfa352455c4 90 // indici per i cicli
pinofal 8:4dfa352455c4 91 int nIndex;
pinofal 8:4dfa352455c4 92 // passo in frequenza fissato dal numero di campioni in cui voglio dividere un periodo di sinusoide: DeltaF = 360°/NUMSAMPLE
pinofal 8:4dfa352455c4 93 double fDeltaF;
pinofal 8:4dfa352455c4 94 // angolo per il quale bisogna calcolare il valore di sinusoide: fAngle = nIndex*DeltaF
pinofal 8:4dfa352455c4 95 double fAngle;
pinofal 8:4dfa352455c4 96
pinofal 8:4dfa352455c4 97 fDeltaF = 360.0/SAMPLESINENUM;
pinofal 8:4dfa352455c4 98 for (nIndex = 0; nIndex < SAMPLESINENUM; nIndex++)
pinofal 8:4dfa352455c4 99 {
pinofal 8:4dfa352455c4 100 fAngle = nIndex*fDeltaF; // angolo per il quale bisogna calcolare il campione di sinusoide
pinofal 8:4dfa352455c4 101 fRads = (PI * fAngle)/180.0; // Convert degree in radian
pinofal 8:4dfa352455c4 102 //usaSine[nIndex] = AMPLITUDE * cos(fRads + PHASE) + OFFSET;
pinofal 8:4dfa352455c4 103 usaSine[nIndex] = nAmplitude * cos(fRads + fPhase) + nOffset;
pinofal 8:4dfa352455c4 104 }
pinofal 8:4dfa352455c4 105 }
pinofal 8:4dfa352455c4 106
pinofal 8:4dfa352455c4 107 //*******************
pinofal 8:4dfa352455c4 108 // Loop Principale
pinofal 8:4dfa352455c4 109 //*******************
pinofal 8:4dfa352455c4 110 int main()
pinofal 8:4dfa352455c4 111 {
pinofal 8:4dfa352455c4 112 //inizializza variabili
pinofal 8:4dfa352455c4 113 bGenerate= false;
pinofal 8:4dfa352455c4 114 bMarimba= true;
pinofal 8:4dfa352455c4 115 bStop= true;
pinofal 8:4dfa352455c4 116 cReadChar= 0;
pinofal 8:4dfa352455c4 117 //nSampleOutIndex= 0;
pinofal 8:4dfa352455c4 118 //nSampleOutCount= 0;
pinofal 8:4dfa352455c4 119 nSampleSoundIndex= 0;
pinofal 8:4dfa352455c4 120
pinofal 8:4dfa352455c4 121 //imposta il funzionamento del pulsante come "PullDown": Aperto = '0'. L'altra modalità di funzionamento è PullUp
pinofal 8:4dfa352455c4 122 myButton.mode(PullUp);
pinofal 8:4dfa352455c4 123
pinofal 8:4dfa352455c4 124 // configura velocità della comunicazione seriale su USB-VirtualCom e invia messaggio di benvenuto
pinofal 8:4dfa352455c4 125 pc.baud(921600); //921600 bps
pinofal 8:4dfa352455c4 126
pinofal 8:4dfa352455c4 127 // messaggio di benvenuto
pinofal 8:4dfa352455c4 128 pc.printf("\r\n Hallo Amaldi Students - Exercise 14 \r\n");
pinofal 8:4dfa352455c4 129 pc.printf("\n\r*** RB-Mab-31: Ultrasound Proximity Sensor ***\n\r");
pinofal 8:4dfa352455c4 130
pinofal 8:4dfa352455c4 131
pinofal 8:4dfa352455c4 132
pinofal 8:4dfa352455c4 133 // INIZIO Genera Sinusoide
pinofal 8:4dfa352455c4 134 fFreq = 440.0; // frequenza in Hz del tono da generare
pinofal 8:4dfa352455c4 135 fAmp = 1.0; // coefficiente per il quale viene moltiplicato l'ampiezza massima del tono da generare
pinofal 8:4dfa352455c4 136 fDeltaT = 1.0/(fFreq*SAMPLESINENUM); // intervallo di tempo tra un campione e l'altro, per generare la frequenza desiderata
pinofal 8:4dfa352455c4 137 CalculateSinewave(32767, (32767*fAmp), (PI/2.0)); // generazione della sinusoide con valori nominali
pinofal 8:4dfa352455c4 138
pinofal 8:4dfa352455c4 139 // Ciclo proncipale
pinofal 8:4dfa352455c4 140 while(true)
pinofal 8:4dfa352455c4 141 {
pinofal 8:4dfa352455c4 142 // Fissa come Output il pin myProx
pinofal 8:4dfa352455c4 143 myProx.output();
pinofal 8:4dfa352455c4 144 // Poni 'L' sul Pin e mantienilo per qualche microsecondo
pinofal 8:4dfa352455c4 145 myProx.write(0);
pinofal 8:4dfa352455c4 146 wait_us(2);
pinofal 8:4dfa352455c4 147 // Poni 'H' sul Pin e mantienilo per qualche microsecondo
pinofal 8:4dfa352455c4 148 myProx.write(1);
pinofal 8:4dfa352455c4 149 wait_us(5);
pinofal 8:4dfa352455c4 150 // Poni 'L' sul Pin e mantienilo per qualche microsecondo
pinofal 8:4dfa352455c4 151 myProx.write(0);
pinofal 8:4dfa352455c4 152 // Attendi assestamento e Fissa come Input il pin myProx
pinofal 8:4dfa352455c4 153 wait_us(2);
pinofal 8:4dfa352455c4 154 myProx.input();
pinofal 8:4dfa352455c4 155
pinofal 8:4dfa352455c4 156 // misura il tempo per cui il pin rimane alto. E' il tempo necessario al suono per raggiungere l'ostacolo e ritornare sul sensore
pinofal 8:4dfa352455c4 157 while(myProx ==0)
pinofal 8:4dfa352455c4 158 {}
pinofal 8:4dfa352455c4 159 myTimer.start();
pinofal 8:4dfa352455c4 160 nTimerStart = myTimer.read_us();
pinofal 8:4dfa352455c4 161 while(myProx == 1)
pinofal 8:4dfa352455c4 162 {}
pinofal 8:4dfa352455c4 163 myTimer.stop();
pinofal 8:4dfa352455c4 164 nTimerStop = myTimer.read_us();
pinofal 8:4dfa352455c4 165
pinofal 8:4dfa352455c4 166 // velocità del suono = 343 [m/s] = 0.0343 [cm/us] = 1/29.1 [cm/us]
pinofal 8:4dfa352455c4 167 // tempo di andata e ritorno del segnale [us] = (TimerStop-TimerStart)[us]; per misurare la distanza bisogna dividere per due questo valore
pinofal 8:4dfa352455c4 168 // distanza dell'ostacolo [cm] = (TimerStop-TimerStart)/2 [us] * 1/29.1[cm/us]
pinofal 8:4dfa352455c4 169 fDistance = (nTimerStop-nTimerStart)/58.2;
pinofal 8:4dfa352455c4 170 //escludi le misure oltre il max
pinofal 8:4dfa352455c4 171 if((fDistance <= 50.0) && (fDistance >= 3))
pinofal 8:4dfa352455c4 172 {
pinofal 8:4dfa352455c4 173 // visualizza il valore misurato
pinofal 8:4dfa352455c4 174 printf("The Distance was %f [cm]\n\r", fDistance);
pinofal 8:4dfa352455c4 175
pinofal 8:4dfa352455c4 176 // SUONA IL CLACSON se l'ostacolo si trova ad una distanza inferiore ad una soglia minima
pinofal 8:4dfa352455c4 177 if(fDistance < 22)
pinofal 8:4dfa352455c4 178 {
pinofal 8:4dfa352455c4 179 // INIZIO generazione tono
pinofal 8:4dfa352455c4 180 nIndex=0;
pinofal 8:4dfa352455c4 181 // Genera il suono del clacson
pinofal 8:4dfa352455c4 182 for(nSampleCount=0; nSampleCount<7000; nSampleCount++)
pinofal 8:4dfa352455c4 183 {
pinofal 8:4dfa352455c4 184 OutWave.write_u16(usaSine[nIndex]); //max 32767
pinofal 8:4dfa352455c4 185 //OutWave.write_u16(32767); //uscita analogica per scopi diagnostici
pinofal 8:4dfa352455c4 186 wait(fDeltaT);
pinofal 8:4dfa352455c4 187 // genera ciclicamente
pinofal 8:4dfa352455c4 188 nIndex++;
pinofal 8:4dfa352455c4 189 if(nIndex >= SAMPLESINENUM)
pinofal 8:4dfa352455c4 190 nIndex=0;
pinofal 8:4dfa352455c4 191 // a metà genera un wait per doppio clacson
pinofal 8:4dfa352455c4 192 if(nSampleCount == 2000)
pinofal 8:4dfa352455c4 193 wait_ms(100);
pinofal 8:4dfa352455c4 194
pinofal 8:4dfa352455c4 195 }
pinofal 8:4dfa352455c4 196 //assicurati di inviare 0 come ultimo campione per spegnere l'amplificatore e non dissipare inutilmente corrente
pinofal 8:4dfa352455c4 197 OutWave.write_u16(0);
pinofal 8:4dfa352455c4 198
pinofal 8:4dfa352455c4 199 } // if(fDistance < soglia) suona clacson
pinofal 8:4dfa352455c4 200 } // if( (fDistance < Max) && (fDistance > Min))
pinofal 8:4dfa352455c4 201 wait_ms(300); // poche misure al secondo per non appesantire il processore
pinofal 8:4dfa352455c4 202 } // while(true)
pinofal 8:4dfa352455c4 203 }