![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
extra test
Dependencies: DHT
newdemo.cpp
- Committer:
- elt14lpo
- Date:
- 2017-05-10
- Revision:
- 0:ef9b24f4c2d9
- Child:
- 1:61ad430f1e5d
File content as of revision 0:ef9b24f4c2d9:
#include "mbed.h" #include <iostream> /* cout */ //#include <stdio.h> /* printf */ #include <math.h> /* sin */ #include <vector> #include <stdlib.h> /* abs */ #include <stdio.h> #include <AnalogIn.h> #include <stdint.h> #//include <DHT.h> #include<sstream> //using namespace std; /* DEBUG FUNCTION // ersätter Debug(xyz) med xyz , där xyz är din kod //För att aktivera: #define Debug(xyz) xyz //För att "stänga av": #define Debug(xyz) //I din kod, skriv din debug kod liknande så här: Debug( std::cout << "My text: " << myVariable << std::endl; ); */ #define Debug(x) x #define DebugPrintState(y) y #define DebugArcSin(z) z //----------VARIABLES HERE int dataLength = 1000; double temp = 25; double hum = 10; double micDist = 150; //millimeters float threshold_1 = 0; //value when going to active mode channel 1 //old hardcoded value = 330 float threshold_2 = 0; //value when going to active mode channel 2 //old hardcoded value = 200 float threshold_adjust = -75; //used to adjust threshold to slightly below max value bool calibratedStatus = false; //flag to make sure Nuclueo only calibrated once for background noise int positionOfMaxVal_1; int positionOfMaxVal_2; const double PI = 3.14159265358979323846; // State machine int STATE; //const int NONE = -1; const int IDLE = 0; const int CALIBRATE = 1; const int LISTEN = 2; const int ACTIVELISTEN = 3; const int CALC = 4; const int CALC_ERROR = 5; const int SEND = 6; //const int WAIT = 9; //dataLength behövs kanske inte, vector klassen kan växa med behov std::vector<float> channel_1(dataLength); std::vector<float> channel_2(dataLength); std::vector<int> timestamps_1(dataLength); std::vector<int> timestamps_2(dataLength); AnalogIn mic1(A0); AnalogIn mic2(A1); AnalogIn mic3(A2); //TIMER Timer t; //led can be used for status DigitalOut led1(LED1); //----------FUNCTIONS HERE //Calculating distance between sound and camera double calcDist(double t, double v){ double s = t*v; return s; } //Calculating angle in radians, D distance between mic1 and mic2 double calcAng(double s, double D){ double ang = asin(s/D); if (ang < 0){ // if angle negative, add 180 degrees return ang + PI ; } else return ang; } //Assuming the input value is temp as a number in degrees celcius and humidity as procent double calcSoundSpeed(double temp, double hum){ //Calculations were done in Matlab double speed = 331.1190 + 0.6016*temp + 0.0126*hum; return speed; } //translate angle to number for camera string convertAngToCamNbr(double ang){ ang = ang*(180 / PI); //radianer till grader double angValues = 270; int stepValues = 50000; string tiltNumber = " 18000"; //hårdkodat Camera Pan värde double oneAng = stepValues/angValues; double cameraAngNumber = ang*oneAng; int panInt = (int)(cameraAngNumber); //double to int //int to string string panNumber; ostringstream convert; convert << panInt; panNumber = convert.str(); string send = panNumber + tiltNumber; return send; } //calc time delay by finding peak values in 2 vectors //channel = 1 or 2 int FindPeak(int channel){ std::vector<float> channel_curr(dataLength); //temporary vector with channel voltage values //if channel 1 then set current channel to channel 1 if (channel == 1){ channel_curr = channel_1; } else channel_curr = channel_2; //reset max value & sum value float valueMax = 0; //reset array position int positionOfMaxVal = 0; //find largest value & mark that position in vectors for (int position = 0; position < channel_curr.size(); position++) { float val = abs(channel_curr[position]); if (val > valueMax ){ valueMax = val; positionOfMaxVal = position; } } return positionOfMaxVal; } double FindTimeDelay(int positionOfMaxVal_1, int positionOfMaxVal_2){ double timemax_1 = timestamps_1[positionOfMaxVal_1]; double timemax_2 = timestamps_2[positionOfMaxVal_2]; double delay = timemax_1 - timemax_2; return delay/1000; //if negative near microphone 1, if positive near micropnone 2 } //get voltage value which represents audio amplitude from microphone float getAudioValue(AnalogIn micX) { return 1000*micX.read(); } bool overThreshold(float micValue_1, float micValue_2){ if ((micValue_1 > threshold_1) || (micValue_2 > threshold_2)){ return true; } else return false; } //true if voltage value in microphone is above the current threshold value bool calibrateThreshold(float micValue, float currentThreshold){ if ( micValue > currentThreshold ){ return true; } else return false; } // main() runs in its own thread in the OS int main() { t.start(); // start timer //while (true) { led1 = !led1; wait(0.5); //STATE MACHINE STATE = IDLE; //int counter = 0; while (true) { switch (STATE) { case IDLE: //always start here DebugPrintState( std::cout << "Nucleo state is IDLE: " << STATE << std::endl; ); Debug( wait(0.5); ); if (!calibratedStatus) STATE = CALIBRATE; else STATE = LISTEN; break; case CALIBRATE: DebugPrintState( std::cout << "Nucleo state is CALIBRATE: " << STATE << std::endl; ); Debug( wait(1); ); //listen for X seconds to background noise, to set accurate threshold value // This should be done only once when rebooting Nucleo float startTime = t.read_us(); float offsetTime = 3000; // milliseconds float blinkTime = 500; while (t.read_us() < (startTime + offsetTime) ) { float micValue_1 = getAudioValue(mic1); if ( calibrateThreshold(micValue_1, threshold_1) ){ threshold_1 = micValue_1 - threshold_adjust; //threshold value updated } float micValue_2 = getAudioValue(mic2); if ( calibrateThreshold(micValue_2, threshold_2) ){ threshold_2 = micValue_2 - threshold_adjust; //threshold value updated } //make LED blink every 500 ms if ( t.read_us() > (startTime + blinkTime) ){ led1 = !led1; blinkTime = blinkTime + 500; } } calibratedStatus = true; STATE = LISTEN; //next state break; case LISTEN: DebugPrintState( std::cout << "Nucleo state is LISTEN: " << STATE << std::endl; ); //Debug( wait(0.5); ); float micValue_1 = getAudioValue(mic1); float micValue_2 = getAudioValue(mic2); if(overThreshold(micValue_1, micValue_2) == true){ //if sound above threshold go to activelisten state //std::cout << "over Threshold!" << std::endl; STATE = ACTIVELISTEN; }else { //std::cout << "under Threshold!" << std::endl; STATE = LISTEN; } break; case ACTIVELISTEN: DebugPrintState( std::cout << "Nucleo state is ACTIVELISTEN: " << STATE << std::endl; ); //Debug( wait(0.5); ); //put value into array, start timer for(int i= 0; i < dataLength; i++){ if (t.read_us() >= INT_MAX){ std::cout << "time out" << std::endl; } //get audio & timestamp values from microphones channel_1[i] = getAudioValue(mic1); timestamps_1[i] = t.read_us(); channel_2[i] = getAudioValue(mic2); timestamps_2[i] = t.read_us(); } //go to state CALC STATE = CALC; break; case CALC: DebugPrintState( std::cout << "Nucleo state is CALC: " << STATE << std::endl; ); //Debug( wait(0.5); ); int positionOfMaxVal_1 = FindPeak(1); int positionOfMaxVal_2 = FindPeak(2); //run functions double timedelay = FindTimeDelay(positionOfMaxVal_1, positionOfMaxVal_2); //milliseconds double speed = calcSoundSpeed(temp, hum); //meters per second double distance = calcDist(timedelay/1000, speed); //millimeters double angle = calcAng((double)distance, micDist); //15cm = 150mm, double type cast because of asin function in angle calculation //go to state SEND if no calc_error Debug( std::cout << "max position for channel 1: " << positionOfMaxVal_1+1 << std::endl; std::cout << "max position for channel 2: " << positionOfMaxVal_2+1 << std::endl; std::cout << "run FindPeak, delay is: " << timedelay << "milliseconds" << std::endl; std::cout << "run calcDist, delta s is: " << distance << "millimeters" << std::endl; std::cout << "run calcAngle, angle is: " << angle << "radians" << std::endl; std::cout<<" run convertAngToCamNbr, coordinates: "<< convertAngToCamNbr(angle)<<std::endl; //return "panNumber tiltNumber"; ); Debug( wait(5); ); if (angle > (3 * PI )/2 || angle < 0 ){ //vinkel larger than 270 eller minde än noll STATE = CALC_ERROR; } else { STATE = SEND; } break; case CALC_ERROR: DebugPrintState( std::cout << "Nucleo state is CALC_ERROR: " << STATE << std::endl; ); Debug( wait(0.5); ); //error message std::cout << "Error. angle not within limits 0 -270 degrees" << std::endl; //nollställ vektorer, , stoppa klockan , osv STATE = LISTEN; break; case SEND: DebugPrintState( std::cout << "Nucleo state is SEND: " << STATE << std::endl; ); Debug( wait(0.5); ); // send coordinates to serial port to camera std::cout<<convertAngToCamNbr(angle)<<std::endl; //return "panNumber tiltNumber"; Debug( wait(0.5); ); STATE = IDLE; break; } } } //GAMMAL TEST KOD NEDANFÖR /* //read audio values and time stamps in ms //make sure that timestamp does not exceed INT_MAX to be able to use int for(int i= 0; i < dataLength; i++){ if (t.read_ms() >= INT_MAX){ std::cout << "time out" << std::endl; } channel_1[i] = getAudioValue(mic1); timestamps_1[i] = t.read_ms(); channel_2[i] = getAudioValue(mic2); timestamps_2[i] = t.read_ms(); } */ //skriv ut alla element i kanal 0 /* std::cout << "channel_1: "; for(int i=0; i<channel_1.size(); ++i){ std::cout << channel_1[i] << ' '; } std::cout << std::endl; */ /* //skriv ut alla time element i kanal 0 std::cout << "timestamps_1: "; for(int i=0; i<timestamps_1.size(); ++i){ std::cout << timestamps_1[i] << ' '; } std::cout << std::endl; */ /* //skriv ut alla element i kanal 1 std::cout << "channel_2: "; for(int i=0; i<channel_2.size(); ++i){ std::cout << channel_2[i] << ' '; } std::cout << std::endl; */ /* //skriv ut alla time element i kanal 1 std::cout << "timestamps_2: "; for(int i=0; i<timestamps_2.size(); ++i){ std::cout << timestamps_2[i] << ' '; } std::cout << std::endl; */ /* int positionOfMaxVal_1 = FindPeak(0); int positionOfMaxVal_2 = FindPeak(1); double timedelay = FindTimeDelay(positionOfMaxVal_1, positionOfMaxVal_2); //milliseconds double speed = calcSoundSpeed(temp, hum); //meters per second double distance = calcDist(timedelay/1000, speed); //millimeters double angle = calcAng((double)distance, micDist); //15cm = 150mm, double type cast because of asin function in angle calculation std::cout << "max position for channel 0: " << positionOfMaxVal_1+1 << std::endl; std::cout << "max position for channel 1: " << positionOfMaxVal_2+1 << std::endl; std::cout << "run FindPeak, delay is: " << timedelay << "milliseconds" << std::endl; std::cout << "run calcDist, delta s is: " << distance << "millimeters" << std::endl; std::cout << "run calcAngle, angle is: " << angle << "degrees" << std::endl; std::cout<<"run convertAngToCamNbr, coordinates"<<convertAngToCamNbr(angle)<<std::endl; //return "panNumber tiltNumber"; t.stop(); //Stop timer */