Program for the water play project for the course Software Testing Practical 2016 given at the VU University

Dependencies:   mbed DRV88255 TextLCD Ping mbed-rtos

Committer:
sbouber1
Date:
Mon Jun 20 13:31:09 2016 +0000
Revision:
70:642153418c6e
Parent:
69:6138d4e0410e
Child:
71:38bb6bf09933
min 1 ml pumping

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sbouber1 28:f4a4ee58d57e 1 #include "PIDController.h"
sbouber1 46:7e4c1f2ab76c 2 #include "LCDController.h"
sbouber1 35:c9261391a995 3
sbouber1 57:8dc3192ff150 4 static DigitalOut heater(p18);
sbouber1 28:f4a4ee58d57e 5
sbouber1 57:8dc3192ff150 6 static DRV8825 mtr_fresh(p21, p27, p28, p29, p22, p23);
sbouber1 57:8dc3192ff150 7 static DRV8825 mtr_salt(p24, p27, p28, p29, p25, p26);
joran 44:7c932cc5991b 8
joran 44:7c932cc5991b 9
sbouber1 28:f4a4ee58d57e 10 // This is called in the main loop on every iteration
sbouber1 28:f4a4ee58d57e 11 void PIDController::update() {
sbouber1 35:c9261391a995 12
sbouber1 57:8dc3192ff150 13 #ifndef TEST_MODE
sbouber1 38:930469a33001 14 if(this->num_iters < STARTUP_ITERATIONS) {
sbouber1 38:930469a33001 15 printf("PIDController: not running, startup phase");
sbouber1 38:930469a33001 16 return;
sbouber1 38:930469a33001 17 }
sbouber1 38:930469a33001 18 #endif
sbouber1 38:930469a33001 19
sbouber1 35:c9261391a995 20 // Control the heater
sbouber1 35:c9261391a995 21 // This could be done in the pumping function as well, if needed
joran 63:59335eb8bdbc 22 if (this->isHeating() && this->temp->getValue() >= TEMP_MIN_UNDESIRED + 1.0f) {
sbouber1 57:8dc3192ff150 23 this->setHeating(false);
joran 62:52cceb263591 24 } else if (!this->isHeating() && this->temp->getValue() < TEMP_MIN_UNDESIRED) {
sbouber1 57:8dc3192ff150 25 this->setHeating(true);
joran 49:ca6fb19fc280 26 }
sbouber1 35:c9261391a995 27
sbouber1 28:f4a4ee58d57e 28 float s = this->salt->getValue();
sbouber1 57:8dc3192ff150 29 float s_in_grams = this->getSaltInGrams();
sbouber1 30:cf12566013a5 30
sbouber1 65:b277b4067d4a 31 if(s < MIN_VALID_SALINITY) {
sbouber1 65:b277b4067d4a 32 cout << "PIDController: Salinity NC, no stabilizing action";
sbouber1 65:b277b4067d4a 33 } else if(s <= SALT_MIN_UNDESIRED) {
sbouber1 30:cf12566013a5 34
sbouber1 57:8dc3192ff150 35 float ml = this->getMlSaltyWater(s_in_grams, this->proximity->getValue());
sbouber1 70:642153418c6e 36 int ml_int = std::min(static_cast<int>(ml), 30);
sbouber1 70:642153418c6e 37 ml_int = std::max(1, ml_int);
sbouber1 30:cf12566013a5 38
sbouber1 65:b277b4067d4a 39 cout << "PIDCONTROLLER: need to pump " << ml_int << " (" << ml << ")" << " ml of salty water\r\n";
sbouber1 30:cf12566013a5 40
sbouber1 35:c9261391a995 41 //this->pump_salt_water(ml_int);
sbouber1 30:cf12566013a5 42
joran 63:59335eb8bdbc 43 } else if(s >= SALT_MAX_UNDESIRED) {
sbouber1 32:1e4919a44196 44
sbouber1 32:1e4919a44196 45 float ml = this->getMlFreshWater(s, this->proximity->getValue());
sbouber1 70:642153418c6e 46 int ml_int = std::min(static_cast<int>(ml), 30);
sbouber1 70:642153418c6e 47 ml_int = std::max(1, ml_int);
sbouber1 32:1e4919a44196 48
sbouber1 65:b277b4067d4a 49 cout << "PIDCONTROLLER: need to pump " << ml_int << " (" << ml << ")" << " ml of fresh water\r\n";
sbouber1 35:c9261391a995 50
sbouber1 35:c9261391a995 51 //this->pump_fresh_water(ml_int);
sbouber1 32:1e4919a44196 52
sbouber1 30:cf12566013a5 53 }
sbouber1 28:f4a4ee58d57e 54 }
sbouber1 28:f4a4ee58d57e 55
sbouber1 57:8dc3192ff150 56 std::string PIDController::getName() {
sbouber1 30:cf12566013a5 57 return "PIDController";
sbouber1 28:f4a4ee58d57e 58 }
sbouber1 28:f4a4ee58d57e 59
joran 29:2b256a7ce0ae 60 //get the salt in the body in grams
sbouber1 57:8dc3192ff150 61 float PIDController::getSaltInGrams() {
sbouber1 57:8dc3192ff150 62 float current_ppt = this->salt->getValue(); //in ppt
sbouber1 57:8dc3192ff150 63 float current_vol = this->proximity->getValue(); //in ml
joran 29:2b256a7ce0ae 64
sbouber1 57:8dc3192ff150 65 return current_ppt * (current_vol / 1000);
joran 29:2b256a7ce0ae 66 }
joran 29:2b256a7ce0ae 67
joran 29:2b256a7ce0ae 68
sbouber1 57:8dc3192ff150 69 void PIDController::pumpSaltWater(int ml) {
sbouber1 57:8dc3192ff150 70 this->pumpWater(&mtr_salt, ml);
sbouber1 32:1e4919a44196 71 }
sbouber1 32:1e4919a44196 72
sbouber1 32:1e4919a44196 73
sbouber1 57:8dc3192ff150 74 void PIDController::pumpFreshWater(int ml) {
sbouber1 57:8dc3192ff150 75 this->pumpWater(&mtr_fresh, ml);
sbouber1 32:1e4919a44196 76 }
sbouber1 32:1e4919a44196 77
sbouber1 57:8dc3192ff150 78
sbouber1 57:8dc3192ff150 79 void PIDController::pumpWater(DRV8825 *mtr, int ml) {
joran 44:7c932cc5991b 80 LCDController::showPumping();
sbouber1 57:8dc3192ff150 81
joran 40:1668630544c7 82 this->pumping = true;
sbouber1 57:8dc3192ff150 83
sbouber1 32:1e4919a44196 84 int j = 5010 * (ml - 1);
sbouber1 32:1e4919a44196 85
sbouber1 32:1e4919a44196 86 for (int i = 500; i < MAX_SPEED; i += 5) {
sbouber1 46:7e4c1f2ab76c 87 mtr->settings(1 / MICROSTEPS_PER_STEP, RIGHT, i);
sbouber1 46:7e4c1f2ab76c 88 }
sbouber1 46:7e4c1f2ab76c 89
sbouber1 46:7e4c1f2ab76c 90 for (int i = 0; i < 2010 + j; i += 1) {
sbouber1 46:7e4c1f2ab76c 91 mtr->settings(1 / MICROSTEPS_PER_STEP, RIGHT, 8000);
sbouber1 46:7e4c1f2ab76c 92 }
sbouber1 46:7e4c1f2ab76c 93
sbouber1 46:7e4c1f2ab76c 94 for (int i = 8000; i > 500; i -= 5) {
sbouber1 46:7e4c1f2ab76c 95 mtr->settings(1 / MICROSTEPS_PER_STEP, RIGHT, i);
sbouber1 46:7e4c1f2ab76c 96 }
sbouber1 46:7e4c1f2ab76c 97
sbouber1 46:7e4c1f2ab76c 98 wait(5);
sbouber1 46:7e4c1f2ab76c 99
sbouber1 46:7e4c1f2ab76c 100 for (int i = 500; i < MAX_SPEED; i += 5) {
sbouber1 32:1e4919a44196 101 mtr->settings(1 / MICROSTEPS_PER_STEP, LEFT, i);
sbouber1 32:1e4919a44196 102 }
sbouber1 32:1e4919a44196 103
sbouber1 32:1e4919a44196 104 for (int i = 0; i < 2010 + j; i += 1) {
sbouber1 32:1e4919a44196 105 mtr->settings(1 / MICROSTEPS_PER_STEP, LEFT, 8000);
sbouber1 32:1e4919a44196 106 }
sbouber1 32:1e4919a44196 107
sbouber1 32:1e4919a44196 108 for (int i = 8000; i > 500; i -= 5) {
sbouber1 32:1e4919a44196 109 mtr->settings(1 / MICROSTEPS_PER_STEP, LEFT, i);
sbouber1 32:1e4919a44196 110 }
sbouber1 32:1e4919a44196 111
sbouber1 46:7e4c1f2ab76c 112 wait(5);
joran 40:1668630544c7 113 this->pumping = false;
sbouber1 32:1e4919a44196 114 }
sbouber1 32:1e4919a44196 115
sbouber1 32:1e4919a44196 116
sbouber1 57:8dc3192ff150 117 float PIDController::getMlSaltyWater(float grams_in_body, float volume_in_body) {
sbouber1 32:1e4919a44196 118
sbouber1 57:8dc3192ff150 119 float solution_gram_per_ten = 1.16f; // 1.0f for our solution
sbouber1 57:8dc3192ff150 120 float sol_volume = 10; // 10ml
sbouber1 32:1e4919a44196 121
sbouber1 57:8dc3192ff150 122 float ideal_ppt_constant = 0.007f; //7 ppt / 1000
sbouber1 57:8dc3192ff150 123 float x1 = volume_in_body * ideal_ppt_constant;
sbouber1 57:8dc3192ff150 124 float x2 = sol_volume * ideal_ppt_constant;
sbouber1 32:1e4919a44196 125
sbouber1 57:8dc3192ff150 126 x1 = x1 - grams_in_body;
sbouber1 57:8dc3192ff150 127 x2 = solution_gram_per_ten - x2;
sbouber1 32:1e4919a44196 128
sbouber1 57:8dc3192ff150 129 float output_ml = (x1 / x2 * sol_volume);
sbouber1 32:1e4919a44196 130
sbouber1 57:8dc3192ff150 131 return output_ml; // amount in ml to get 7 ppt.
sbouber1 35:c9261391a995 132 }
sbouber1 35:c9261391a995 133
sbouber1 57:8dc3192ff150 134 bool PIDController::isHeating() {
sbouber1 35:c9261391a995 135 return this->heating;
sbouber1 35:c9261391a995 136 }
sbouber1 35:c9261391a995 137
sbouber1 57:8dc3192ff150 138 bool PIDController::isPumping() {
joran 40:1668630544c7 139 return this->pumping;
joran 40:1668630544c7 140 }
joran 40:1668630544c7 141
sbouber1 57:8dc3192ff150 142 void PIDController::setHeating(bool enabled) {
sbouber1 35:c9261391a995 143 if(enabled == this->heating) return;
sbouber1 35:c9261391a995 144
sbouber1 35:c9261391a995 145 this->heating = enabled;
sbouber1 35:c9261391a995 146 if(enabled) {
sbouber1 57:8dc3192ff150 147 #ifdef TEST_MODE
sbouber1 35:c9261391a995 148 printf("Should set heater to 1\r\n");
sbouber1 35:c9261391a995 149 #else
sbouber1 35:c9261391a995 150 heater = 1;
sbouber1 35:c9261391a995 151 #endif
sbouber1 35:c9261391a995 152 } else {
sbouber1 57:8dc3192ff150 153 #ifdef TEST_MODE
sbouber1 35:c9261391a995 154 printf("Should set heater to 0\r\n");
sbouber1 35:c9261391a995 155 #else
sbouber1 35:c9261391a995 156 heater = 0;
sbouber1 35:c9261391a995 157 #endif
sbouber1 32:1e4919a44196 158 }
sbouber1 35:c9261391a995 159 }
sbouber1 32:1e4919a44196 160
sbouber1 32:1e4919a44196 161 float PIDController::getMlFreshWater(float ppt, float volume) {
sbouber1 32:1e4919a44196 162 return (volume * (ppt / 7.0)) - volume;
sbouber1 32:1e4919a44196 163 }
sbouber1 32:1e4919a44196 164
sbouber1 46:7e4c1f2ab76c 165 void PIDController::doTestingStuff(int ml) {
sbouber1 46:7e4c1f2ab76c 166 while(1)
sbouber1 57:8dc3192ff150 167 this->pumpSaltWater(ml);
sbouber1 46:7e4c1f2ab76c 168 }
sbouber1 46:7e4c1f2ab76c 169