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
ProxSensor.cpp@8:4dfa352455c4, 2018-11-20 (annotated)
- Committer:
- pinofal
- Date:
- Tue Nov 20 11:13:44 2018 +0000
- Revision:
- 8:4dfa352455c4
Proximity UltrasoundSensor + Clacson
Who changed what in which revision?
User | Revision | Line number | New 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 | } |