Amaldi / Mbed 2 deprecated Amaldi_14_Exercise_ProxSensor

Dependencies:   mbed

ProxSensor.cpp

Committer:
pinofal
Date:
2018-11-20
Revision:
8:4dfa352455c4

File content as of revision 8:4dfa352455c4:

// 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)
}