Felix W
/
PM2_Example_PES_board_waldsfel
Workshop2
main.cpp@13:bc1df4256578, 2021-04-21 (annotated)
- Committer:
- waldsfel
- Date:
- Wed Apr 21 15:07:50 2021 +0000
- Revision:
- 13:bc1df4256578
- Parent:
- 12:e5be1469bc76
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
waldsfel | 13:bc1df4256578 | 1 | //Buttons zum ein und ausschalten der Messung |
waldsfel | 13:bc1df4256578 | 2 | |
waldsfel | 13:bc1df4256578 | 3 | //Sensor data sheet https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/8_Differential_Pressure/Datasheets/Sensirion_Differential_Pressure_Datasheet_SdP8xx_Analog.pdf |
waldsfel | 13:bc1df4256578 | 4 | |
waldsfel | 13:bc1df4256578 | 5 | //Messung via printf auf CMD Zeil ausgeben, mit P5 serial connector verscuchen abzugreifen |
waldsfel | 13:bc1df4256578 | 6 | |
waldsfel | 13:bc1df4256578 | 7 | //Druck respektive die Konstruktion zum Sensor & Ventouri vorbereiten |
waldsfel | 13:bc1df4256578 | 8 | |
waldsfel | 13:bc1df4256578 | 9 | //Ventouri richtig rechnen, mit Luftvolumen von Lunge und der Range des Sensors |
waldsfel | 13:bc1df4256578 | 10 | |
waldsfel | 13:bc1df4256578 | 11 | //Baud Rate 115200 |
waldsfel | 13:bc1df4256578 | 12 | |
waldsfel | 13:bc1df4256578 | 13 | |
pmic | 1:93d997d6b232 | 14 | #include "mbed.h" |
pmic | 1:93d997d6b232 | 15 | #include "platform/mbed_thread.h" |
pmic | 6:e1fa1a2d7483 | 16 | |
pmic | 6:e1fa1a2d7483 | 17 | /* PM2_Libary */ |
pmic | 1:93d997d6b232 | 18 | #include "EncoderCounter.h" |
pmic | 1:93d997d6b232 | 19 | #include "Servo.h" |
pmic | 3:d22942631cd7 | 20 | #include "SpeedController.h" |
pmic | 9:f10b974d01e0 | 21 | #include "FastPWM.h" |
pmic | 11:af0f165f8761 | 22 | #include "RangeFinder.h" |
pmic | 6:e1fa1a2d7483 | 23 | |
waldsfel | 13:bc1df4256578 | 24 | #include "math.h" |
waldsfel | 13:bc1df4256578 | 25 | |
pmic | 6:e1fa1a2d7483 | 26 | using namespace std::chrono; |
pmic | 6:e1fa1a2d7483 | 27 | |
pmic | 8:9bb806a7f585 | 28 | InterruptIn user_button(USER_BUTTON); |
waldsfel | 13:bc1df4256578 | 29 | DigitalOut led(LED1); |
waldsfel | 13:bc1df4256578 | 30 | Timer runtimeTimer, user_button_timer; |
pmic | 6:e1fa1a2d7483 | 31 | |
waldsfel | 13:bc1df4256578 | 32 | bool executeMainTask = false; |
waldsfel | 13:bc1df4256578 | 33 | int Ts_ms = 50; |
pmic | 6:e1fa1a2d7483 | 34 | |
waldsfel | 13:bc1df4256578 | 35 | //initialize functions |
pmic | 6:e1fa1a2d7483 | 36 | void button_fall(); |
pmic | 6:e1fa1a2d7483 | 37 | void button_rise(); |
waldsfel | 13:bc1df4256578 | 38 | float readSensor(AnalogIn sensor); |
waldsfel | 13:bc1df4256578 | 39 | float map_pressure_sensor(float input); |
waldsfel | 13:bc1df4256578 | 40 | void printP5(int value); |
waldsfel | 13:bc1df4256578 | 41 | void printSerialPlotter(int v1 , int v2); |
waldsfel | 13:bc1df4256578 | 42 | float venturiSpeed(float DiaEntry, float DiaNarrow, float densAir, float dP); |
waldsfel | 13:bc1df4256578 | 43 | float venturiFlow(int timeStart, int timeStop); |
waldsfel | 13:bc1df4256578 | 44 | float getCirlceArea(float diameter); |
waldsfel | 13:bc1df4256578 | 45 | //float detectBreath(float aiflow, int start, int stop); |
waldsfel | 13:bc1df4256578 | 46 | bool detectBreath(float mappedSensorValue); |
pmic | 6:e1fa1a2d7483 | 47 | |
waldsfel | 13:bc1df4256578 | 48 | //Analog Port for sensor |
waldsfel | 13:bc1df4256578 | 49 | AnalogIn analogIn(PA_0); |
waldsfel | 13:bc1df4256578 | 50 | float pressureDifference = 0.0f; |
waldsfel | 13:bc1df4256578 | 51 | float VDD = 3.3f; |
waldsfel | 13:bc1df4256578 | 52 | |
pmic | 6:e1fa1a2d7483 | 53 | |
waldsfel | 13:bc1df4256578 | 54 | //Venturi Pipe parameters |
waldsfel | 13:bc1df4256578 | 55 | float DiaEntry = 6 * 10e-3; //m |
waldsfel | 13:bc1df4256578 | 56 | float DiaNarrow = 2.2 * 10e-3; //m |
waldsfel | 13:bc1df4256578 | 57 | float densityAir = 1.2041; //kg/m^3 |
waldsfel | 13:bc1df4256578 | 58 | float pi = 3.14159; |
waldsfel | 13:bc1df4256578 | 59 | int threshold = 5; |
pmic | 6:e1fa1a2d7483 | 60 | |
waldsfel | 13:bc1df4256578 | 61 | int nBreath = 0; |
waldsfel | 13:bc1df4256578 | 62 | float totalBreathVolume = 0; |
waldsfel | 13:bc1df4256578 | 63 | float currentBreathVolume = 0; |
pmic | 1:93d997d6b232 | 64 | |
waldsfel | 13:bc1df4256578 | 65 | int main(){ |
waldsfel | 13:bc1df4256578 | 66 | |
waldsfel | 13:bc1df4256578 | 67 | int i = 0; |
waldsfel | 13:bc1df4256578 | 68 | runtimeTimer.start(); |
pmic | 6:e1fa1a2d7483 | 69 | user_button.fall(&button_fall); |
pmic | 6:e1fa1a2d7483 | 70 | user_button.rise(&button_rise); |
waldsfel | 13:bc1df4256578 | 71 | int last_print = -999999; |
pmic | 6:e1fa1a2d7483 | 72 | |
waldsfel | 13:bc1df4256578 | 73 | // printf("System running %f\n\r", pressureDifference); |
waldsfel | 13:bc1df4256578 | 74 | while(true){ |
waldsfel | 13:bc1df4256578 | 75 | if (executeMainTask){ |
waldsfel | 13:bc1df4256578 | 76 | |
waldsfel | 13:bc1df4256578 | 77 | i = 0; |
pmic | 6:e1fa1a2d7483 | 78 | |
waldsfel | 13:bc1df4256578 | 79 | //pressureDifference = analogIn.read()*VDD; |
waldsfel | 13:bc1df4256578 | 80 | pressureDifference = readSensor(analogIn); |
waldsfel | 13:bc1df4256578 | 81 | float dP = map_pressure_sensor(pressureDifference); |
waldsfel | 13:bc1df4256578 | 82 | |
waldsfel | 13:bc1df4256578 | 83 | int timestamp = runtimeTimer.elapsed_time().count(); |
waldsfel | 13:bc1df4256578 | 84 | float speed = venturiSpeed(DiaEntry, DiaNarrow, densityAir, dP); |
waldsfel | 13:bc1df4256578 | 85 | float airVolume = venturiFlow(timestamp, last_print); |
waldsfel | 13:bc1df4256578 | 86 | totalBreathVolume += airVolume; |
waldsfel | 13:bc1df4256578 | 87 | if (detectBreath(dP)){ |
waldsfel | 13:bc1df4256578 | 88 | currentBreathVolume += airVolume; |
waldsfel | 13:bc1df4256578 | 89 | } else if (!detectBreath(dP)){ |
waldsfel | 13:bc1df4256578 | 90 | currentBreathVolume *= 0.1; |
waldsfel | 12:e5be1469bc76 | 91 | } |
waldsfel | 13:bc1df4256578 | 92 | if ((timestamp-last_print) > 50000){ |
waldsfel | 13:bc1df4256578 | 93 | //printf("%d, %d, %f, %f, %f, %f, %f, %f\n\r", timestamp,last_print,dP, pressureDifference,speed, airVolume, currentBreathVolume ,totalBreathVolume); |
waldsfel | 13:bc1df4256578 | 94 | printf("%f, %f, %f, %f, %f, %f\n\r", dP, pressureDifference,speed, airVolume, currentBreathVolume ,totalBreathVolume); |
waldsfel | 13:bc1df4256578 | 95 | last_print = timestamp; |
waldsfel | 13:bc1df4256578 | 96 | |
waldsfel | 13:bc1df4256578 | 97 | } |
waldsfel | 13:bc1df4256578 | 98 | led != led; |
pmic | 1:93d997d6b232 | 99 | } |
pmic | 6:e1fa1a2d7483 | 100 | |
waldsfel | 13:bc1df4256578 | 101 | else { |
waldsfel | 13:bc1df4256578 | 102 | if (i==0){ |
waldsfel | 13:bc1df4256578 | 103 | printf("Program paused, waiting until button gets pressed!\r\n"); |
waldsfel | 13:bc1df4256578 | 104 | i = 1; |
waldsfel | 13:bc1df4256578 | 105 | } |
waldsfel | 13:bc1df4256578 | 106 | } |
pmic | 1:93d997d6b232 | 107 | } |
pmic | 1:93d997d6b232 | 108 | } |
pmic | 6:e1fa1a2d7483 | 109 | |
pmic | 6:e1fa1a2d7483 | 110 | void button_fall() |
pmic | 6:e1fa1a2d7483 | 111 | { |
pmic | 6:e1fa1a2d7483 | 112 | user_button_timer.reset(); |
pmic | 6:e1fa1a2d7483 | 113 | user_button_timer.start(); |
pmic | 6:e1fa1a2d7483 | 114 | } |
waldsfel | 13:bc1df4256578 | 115 | |
pmic | 6:e1fa1a2d7483 | 116 | void button_rise() |
pmic | 6:e1fa1a2d7483 | 117 | { |
waldsfel | 13:bc1df4256578 | 118 | int t_button = duration_cast<milliseconds>(user_button_timer.elapsed_time()).count(); |
pmic | 6:e1fa1a2d7483 | 119 | user_button_timer.stop(); |
waldsfel | 13:bc1df4256578 | 120 | if(t_button > 200) executeMainTask = !executeMainTask; |
waldsfel | 13:bc1df4256578 | 121 | } |
waldsfel | 13:bc1df4256578 | 122 | |
waldsfel | 13:bc1df4256578 | 123 | float readSensor(AnalogIn sensor){ |
waldsfel | 13:bc1df4256578 | 124 | return sensor.read() * VDD; |
waldsfel | 13:bc1df4256578 | 125 | } |
waldsfel | 13:bc1df4256578 | 126 | |
waldsfel | 13:bc1df4256578 | 127 | float map_pressure_sensor(float input){ |
waldsfel | 13:bc1df4256578 | 128 | float dP; |
waldsfel | 13:bc1df4256578 | 129 | dP = ((750*input)/VDD) - 150; |
waldsfel | 13:bc1df4256578 | 130 | if (abs(dP)< threshold){ //Filtering out noise |
waldsfel | 13:bc1df4256578 | 131 | dP = 0; |
waldsfel | 13:bc1df4256578 | 132 | } |
waldsfel | 13:bc1df4256578 | 133 | |
waldsfel | 13:bc1df4256578 | 134 | |
waldsfel | 13:bc1df4256578 | 135 | return dP; |
waldsfel | 13:bc1df4256578 | 136 | } |
waldsfel | 13:bc1df4256578 | 137 | |
waldsfel | 13:bc1df4256578 | 138 | void printP5(int value){ |
waldsfel | 13:bc1df4256578 | 139 | printf("%d\r\n", value); |
waldsfel | 13:bc1df4256578 | 140 | } |
waldsfel | 13:bc1df4256578 | 141 | |
waldsfel | 13:bc1df4256578 | 142 | void printSerialPlotter(int v1 , int v2){ |
waldsfel | 13:bc1df4256578 | 143 | printf("%d %d",v1,v2); |
waldsfel | 13:bc1df4256578 | 144 | } |
waldsfel | 13:bc1df4256578 | 145 | |
waldsfel | 13:bc1df4256578 | 146 | float venturiSpeed(float DiaEntry, float DiaNarrow, float densAir, float dP){ |
waldsfel | 13:bc1df4256578 | 147 | //formula https://www.leifiphysik.de/mechanik/stroemungslehre/ausblick/venturi-rohr |
waldsfel | 13:bc1df4256578 | 148 | float vEntry; |
waldsfel | 13:bc1df4256578 | 149 | float A1 = getCirlceArea(DiaEntry); |
waldsfel | 13:bc1df4256578 | 150 | float A2 = getCirlceArea(DiaNarrow); |
waldsfel | 13:bc1df4256578 | 151 | float absdP = abs(dP); |
waldsfel | 13:bc1df4256578 | 152 | vEntry = sqrt(abs((2*dP)/(densAir*((pow((A1-A2),2)-1))))); |
waldsfel | 13:bc1df4256578 | 153 | if(dP < 0){ |
waldsfel | 13:bc1df4256578 | 154 | vEntry = (-1)*vEntry; |
waldsfel | 13:bc1df4256578 | 155 | } |
waldsfel | 13:bc1df4256578 | 156 | return vEntry; |
waldsfel | 13:bc1df4256578 | 157 | } |
waldsfel | 13:bc1df4256578 | 158 | |
waldsfel | 13:bc1df4256578 | 159 | float venturiFlow(int timeStart, int timeStop){ |
waldsfel | 13:bc1df4256578 | 160 | float volume; |
waldsfel | 13:bc1df4256578 | 161 | float flowSpeed = venturiSpeed(DiaEntry, DiaNarrow, densityAir, map_pressure_sensor(pressureDifference)); |
waldsfel | 13:bc1df4256578 | 162 | float flowRate = flowSpeed * getCirlceArea(DiaEntry); |
waldsfel | 13:bc1df4256578 | 163 | int timeDelate = timeStop - timeStart; //Microseconds |
waldsfel | 13:bc1df4256578 | 164 | volume = timeDelate *10e-6 * flowRate; //to SI |
waldsfel | 13:bc1df4256578 | 165 | return abs(volume); |
waldsfel | 13:bc1df4256578 | 166 | } |
waldsfel | 13:bc1df4256578 | 167 | |
waldsfel | 13:bc1df4256578 | 168 | float getCirlceArea(float diameter){ |
waldsfel | 13:bc1df4256578 | 169 | float area = (pow(diameter/2,2))*pi; |
waldsfel | 13:bc1df4256578 | 170 | return area; |
waldsfel | 13:bc1df4256578 | 171 | } |
waldsfel | 13:bc1df4256578 | 172 | |
waldsfel | 13:bc1df4256578 | 173 | bool detectBreath(float mappedSensorValue){ |
waldsfel | 13:bc1df4256578 | 174 | if (mappedSensorValue > 6){ |
waldsfel | 13:bc1df4256578 | 175 | return true; |
waldsfel | 13:bc1df4256578 | 176 | }else{ |
waldsfel | 13:bc1df4256578 | 177 | return false; |
pmic | 8:9bb806a7f585 | 178 | } |
pmic | 6:e1fa1a2d7483 | 179 | } |