extra test

Dependencies:   DHT

Revision:
0:ef9b24f4c2d9
Child:
1:61ad430f1e5d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/newdemo.cpp	Wed May 10 13:19:59 2017 +0000
@@ -0,0 +1,382 @@
+#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
+*/