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
Diff: ProxSensor.cpp
- Revision:
- 8:4dfa352455c4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProxSensor.cpp Tue Nov 20 11:13:44 2018 +0000 @@ -0,0 +1,203 @@ +// Tested : NUCLEO F207ZG +//#include "SoundSample.h" +#include "mbed.h" +#include<stdlib.h> + + + +// numero di campioni che compongono un periodo della sinusoide in Output sull'ADC +#define SAMPLESINENUM 45 // consigliabile avere multipli di 45 + +// parametri dell'onda coseno da generare +#define PI (3.141592653589793238462) +#define AMPLITUDE 32767 //(1.0) // x * 3.3V +#define PHASE (PI/2) // 2*pi è un periodo +#define OFFSET 32767 //(0x7FFF) + +// numero di note componenti la scala diatonica della marimba +#define NUMTONE 120 + +// Definizione periferiche +Serial pc(USBTX, USBRX); +AnalogOut OutWave(PA_4); // pin A2 di output per la forma d'onda analogica +DigitalOut OutPulse(PC_0); +DigitalIn myButton(USER_BUTTON); // User Button +//DigitalOut led1(LED1); +DigitalOut led2(LED2); +//DigitalOut led3(LED3); +DigitalInOut myProx (PC_0, PIN_OUTPUT, PullNone, 0); +Timer myTimer; + +// ticker per la generazione dell'onda con DAC +Ticker SampleOutTicker; + +// Buffer contenente la sinusoide da porre in output. +unsigned short usaSine[SAMPLESINENUM]; + +// prototipo di funzione che genera i campioni della sinusoide da utilizzare per la generazione tramite DAC +void CalculateSinewave(void); +// funzione di generazione suono della frequenza e ampiezza selezionate +void SoundGenerate(double fFrequency); + +// carattere in arrivo dal PC +volatile char cReadChar; +volatile char CReadMusic; +// indice, nell'array, del campione da porre in output +//volatile int nSampleOutIndex; +// contatore dei campioni in output sul DAC +//volatile int nSampleOutCount; + +// indice nell'array dei campioni da porre in output da DAC per Marimba +volatile int nSampleSoundIndex; + +// Periodo di generazione campioni in output DeltaT = T/NumSample +double fDeltaT; +// amplificazione per il dato da spedire sull'ADC +volatile double fAmp; +//volatile double fAmpNew; +// flag per bloccare la generazione del segnale +volatile int bGenerate = false; +// flag per indicare se è richiesta la generazione del suono di marimba +volatile int bMarimba = false; +// frequenza segnale da generare +volatile double fFreq; +//flag che diventa true se bisogna fermare la generazione di suoni +volatile int bStop=true; +// periodo della sinusoide da generare +double fPeriod; +// tipo di suono da generare: 0=Sine, 1= Square +char cSoundWave; +// nota corrispondente al tasto premuto +volatile char cKeyToPlay= '\0'; +// indice per i cicli +volatile int nIndex; + +// numero di campioni presenti in 2 secondi +int nSampleCount; + +// inizio e fine del timer che misura la distanza con il sensore ultrasuoni +int nTimerStart, nTimerStop; +// distanza in cm dell'ostacolo +double fDistance; + +//**************************** +// Create the sinewave buffer +//**************************** +void CalculateSinewave(int nOffset, int nAmplitude, double fPhase) +{ + // variabile contenente l'angolo in radianti + double fRads; + // indici per i cicli + int nIndex; + // passo in frequenza fissato dal numero di campioni in cui voglio dividere un periodo di sinusoide: DeltaF = 360°/NUMSAMPLE + double fDeltaF; + // angolo per il quale bisogna calcolare il valore di sinusoide: fAngle = nIndex*DeltaF + double fAngle; + + fDeltaF = 360.0/SAMPLESINENUM; + for (nIndex = 0; nIndex < SAMPLESINENUM; nIndex++) + { + fAngle = nIndex*fDeltaF; // angolo per il quale bisogna calcolare il campione di sinusoide + fRads = (PI * fAngle)/180.0; // Convert degree in radian + //usaSine[nIndex] = AMPLITUDE * cos(fRads + PHASE) + OFFSET; + usaSine[nIndex] = nAmplitude * cos(fRads + fPhase) + nOffset; + } +} + +//******************* +// Loop Principale +//******************* +int main() +{ + //inizializza variabili + bGenerate= false; + bMarimba= true; + bStop= true; + cReadChar= 0; + //nSampleOutIndex= 0; + //nSampleOutCount= 0; + nSampleSoundIndex= 0; + + //imposta il funzionamento del pulsante come "PullDown": Aperto = '0'. L'altra modalità di funzionamento è PullUp + myButton.mode(PullUp); + + // configura velocità della comunicazione seriale su USB-VirtualCom e invia messaggio di benvenuto + pc.baud(921600); //921600 bps + + // messaggio di benvenuto + pc.printf("\r\n Hallo Amaldi Students - Exercise 14 \r\n"); + pc.printf("\n\r*** RB-Mab-31: Ultrasound Proximity Sensor ***\n\r"); + + + + // INIZIO Genera Sinusoide + fFreq = 440.0; // frequenza in Hz del tono da generare + fAmp = 1.0; // coefficiente per il quale viene moltiplicato l'ampiezza massima del tono da generare + fDeltaT = 1.0/(fFreq*SAMPLESINENUM); // intervallo di tempo tra un campione e l'altro, per generare la frequenza desiderata + CalculateSinewave(32767, (32767*fAmp), (PI/2.0)); // generazione della sinusoide con valori nominali + + // Ciclo proncipale + while(true) + { + // Fissa come Output il pin myProx + myProx.output(); + // Poni 'L' sul Pin e mantienilo per qualche microsecondo + myProx.write(0); + wait_us(2); + // Poni 'H' sul Pin e mantienilo per qualche microsecondo + myProx.write(1); + wait_us(5); + // Poni 'L' sul Pin e mantienilo per qualche microsecondo + myProx.write(0); + // Attendi assestamento e Fissa come Input il pin myProx + wait_us(2); + myProx.input(); + + // misura il tempo per cui il pin rimane alto. E' il tempo necessario al suono per raggiungere l'ostacolo e ritornare sul sensore + while(myProx ==0) + {} + myTimer.start(); + nTimerStart = myTimer.read_us(); + while(myProx == 1) + {} + myTimer.stop(); + nTimerStop = myTimer.read_us(); + + // velocità del suono = 343 [m/s] = 0.0343 [cm/us] = 1/29.1 [cm/us] + // tempo di andata e ritorno del segnale [us] = (TimerStop-TimerStart)[us]; per misurare la distanza bisogna dividere per due questo valore + // distanza dell'ostacolo [cm] = (TimerStop-TimerStart)/2 [us] * 1/29.1[cm/us] + fDistance = (nTimerStop-nTimerStart)/58.2; + //escludi le misure oltre il max + if((fDistance <= 50.0) && (fDistance >= 3)) + { + // visualizza il valore misurato + printf("The Distance was %f [cm]\n\r", fDistance); + + // SUONA IL CLACSON se l'ostacolo si trova ad una distanza inferiore ad una soglia minima + if(fDistance < 22) + { + // INIZIO generazione tono + nIndex=0; + // Genera il suono del clacson + for(nSampleCount=0; nSampleCount<7000; nSampleCount++) + { + OutWave.write_u16(usaSine[nIndex]); //max 32767 + //OutWave.write_u16(32767); //uscita analogica per scopi diagnostici + wait(fDeltaT); + // genera ciclicamente + nIndex++; + if(nIndex >= SAMPLESINENUM) + nIndex=0; + // a metà genera un wait per doppio clacson + if(nSampleCount == 2000) + wait_ms(100); + + } + //assicurati di inviare 0 come ultimo campione per spegnere l'amplificatore e non dissipare inutilmente corrente + OutWave.write_u16(0); + + } // if(fDistance < soglia) suona clacson + } // if( (fDistance < Max) && (fDistance > Min)) + wait_ms(300); // poche misure al secondo per non appesantire il processore + } // while(true) +} \ No newline at end of file