Amaldi / Mbed 2 deprecated Amaldi_14_Exercise_ProxSensor

Dependencies:   mbed

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