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:28:21 2016 +0000
Revision:
69:6138d4e0410e
Parent:
65:b277b4067d4a
Child:
70:642153418c6e
max 30 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 69:6138d4e0410e 36 int ml_int = std::max(static_cast<int>(ml), 30);
sbouber1 30:cf12566013a5 37
sbouber1 65:b277b4067d4a 38 cout << "PIDCONTROLLER: need to pump " << ml_int << " (" << ml << ")" << " ml of salty water\r\n";
sbouber1 30:cf12566013a5 39
sbouber1 35:c9261391a995 40 //this->pump_salt_water(ml_int);
sbouber1 30:cf12566013a5 41
joran 63:59335eb8bdbc 42 } else if(s >= SALT_MAX_UNDESIRED) {
sbouber1 32:1e4919a44196 43
sbouber1 32:1e4919a44196 44 float ml = this->getMlFreshWater(s, this->proximity->getValue());
sbouber1 69:6138d4e0410e 45 int ml_int = std::max(static_cast<int>(ml), 30);
sbouber1 32:1e4919a44196 46
sbouber1 65:b277b4067d4a 47 cout << "PIDCONTROLLER: need to pump " << ml_int << " (" << ml << ")" << " ml of fresh water\r\n";
sbouber1 35:c9261391a995 48
sbouber1 35:c9261391a995 49 //this->pump_fresh_water(ml_int);
sbouber1 32:1e4919a44196 50
sbouber1 30:cf12566013a5 51 }
sbouber1 28:f4a4ee58d57e 52 }
sbouber1 28:f4a4ee58d57e 53
sbouber1 57:8dc3192ff150 54 std::string PIDController::getName() {
sbouber1 30:cf12566013a5 55 return "PIDController";
sbouber1 28:f4a4ee58d57e 56 }
sbouber1 28:f4a4ee58d57e 57
joran 29:2b256a7ce0ae 58 //get the salt in the body in grams
sbouber1 57:8dc3192ff150 59 float PIDController::getSaltInGrams() {
sbouber1 57:8dc3192ff150 60 float current_ppt = this->salt->getValue(); //in ppt
sbouber1 57:8dc3192ff150 61 float current_vol = this->proximity->getValue(); //in ml
joran 29:2b256a7ce0ae 62
sbouber1 57:8dc3192ff150 63 return current_ppt * (current_vol / 1000);
joran 29:2b256a7ce0ae 64 }
joran 29:2b256a7ce0ae 65
joran 29:2b256a7ce0ae 66
sbouber1 57:8dc3192ff150 67 void PIDController::pumpSaltWater(int ml) {
sbouber1 57:8dc3192ff150 68 this->pumpWater(&mtr_salt, ml);
sbouber1 32:1e4919a44196 69 }
sbouber1 32:1e4919a44196 70
sbouber1 32:1e4919a44196 71
sbouber1 57:8dc3192ff150 72 void PIDController::pumpFreshWater(int ml) {
sbouber1 57:8dc3192ff150 73 this->pumpWater(&mtr_fresh, ml);
sbouber1 32:1e4919a44196 74 }
sbouber1 32:1e4919a44196 75
sbouber1 57:8dc3192ff150 76
sbouber1 57:8dc3192ff150 77 void PIDController::pumpWater(DRV8825 *mtr, int ml) {
joran 44:7c932cc5991b 78 LCDController::showPumping();
sbouber1 57:8dc3192ff150 79
joran 40:1668630544c7 80 this->pumping = true;
sbouber1 57:8dc3192ff150 81
sbouber1 32:1e4919a44196 82 int j = 5010 * (ml - 1);
sbouber1 32:1e4919a44196 83
sbouber1 32:1e4919a44196 84 for (int i = 500; i < MAX_SPEED; i += 5) {
sbouber1 46:7e4c1f2ab76c 85 mtr->settings(1 / MICROSTEPS_PER_STEP, RIGHT, i);
sbouber1 46:7e4c1f2ab76c 86 }
sbouber1 46:7e4c1f2ab76c 87
sbouber1 46:7e4c1f2ab76c 88 for (int i = 0; i < 2010 + j; i += 1) {
sbouber1 46:7e4c1f2ab76c 89 mtr->settings(1 / MICROSTEPS_PER_STEP, RIGHT, 8000);
sbouber1 46:7e4c1f2ab76c 90 }
sbouber1 46:7e4c1f2ab76c 91
sbouber1 46:7e4c1f2ab76c 92 for (int i = 8000; i > 500; i -= 5) {
sbouber1 46:7e4c1f2ab76c 93 mtr->settings(1 / MICROSTEPS_PER_STEP, RIGHT, i);
sbouber1 46:7e4c1f2ab76c 94 }
sbouber1 46:7e4c1f2ab76c 95
sbouber1 46:7e4c1f2ab76c 96 wait(5);
sbouber1 46:7e4c1f2ab76c 97
sbouber1 46:7e4c1f2ab76c 98 for (int i = 500; i < MAX_SPEED; i += 5) {
sbouber1 32:1e4919a44196 99 mtr->settings(1 / MICROSTEPS_PER_STEP, LEFT, i);
sbouber1 32:1e4919a44196 100 }
sbouber1 32:1e4919a44196 101
sbouber1 32:1e4919a44196 102 for (int i = 0; i < 2010 + j; i += 1) {
sbouber1 32:1e4919a44196 103 mtr->settings(1 / MICROSTEPS_PER_STEP, LEFT, 8000);
sbouber1 32:1e4919a44196 104 }
sbouber1 32:1e4919a44196 105
sbouber1 32:1e4919a44196 106 for (int i = 8000; i > 500; i -= 5) {
sbouber1 32:1e4919a44196 107 mtr->settings(1 / MICROSTEPS_PER_STEP, LEFT, i);
sbouber1 32:1e4919a44196 108 }
sbouber1 32:1e4919a44196 109
sbouber1 46:7e4c1f2ab76c 110 wait(5);
joran 40:1668630544c7 111 this->pumping = false;
sbouber1 32:1e4919a44196 112 }
sbouber1 32:1e4919a44196 113
sbouber1 32:1e4919a44196 114
sbouber1 57:8dc3192ff150 115 float PIDController::getMlSaltyWater(float grams_in_body, float volume_in_body) {
sbouber1 32:1e4919a44196 116
sbouber1 57:8dc3192ff150 117 float solution_gram_per_ten = 1.16f; // 1.0f for our solution
sbouber1 57:8dc3192ff150 118 float sol_volume = 10; // 10ml
sbouber1 32:1e4919a44196 119
sbouber1 57:8dc3192ff150 120 float ideal_ppt_constant = 0.007f; //7 ppt / 1000
sbouber1 57:8dc3192ff150 121 float x1 = volume_in_body * ideal_ppt_constant;
sbouber1 57:8dc3192ff150 122 float x2 = sol_volume * ideal_ppt_constant;
sbouber1 32:1e4919a44196 123
sbouber1 57:8dc3192ff150 124 x1 = x1 - grams_in_body;
sbouber1 57:8dc3192ff150 125 x2 = solution_gram_per_ten - x2;
sbouber1 32:1e4919a44196 126
sbouber1 57:8dc3192ff150 127 float output_ml = (x1 / x2 * sol_volume);
sbouber1 32:1e4919a44196 128
sbouber1 57:8dc3192ff150 129 return output_ml; // amount in ml to get 7 ppt.
sbouber1 35:c9261391a995 130 }
sbouber1 35:c9261391a995 131
sbouber1 57:8dc3192ff150 132 bool PIDController::isHeating() {
sbouber1 35:c9261391a995 133 return this->heating;
sbouber1 35:c9261391a995 134 }
sbouber1 35:c9261391a995 135
sbouber1 57:8dc3192ff150 136 bool PIDController::isPumping() {
joran 40:1668630544c7 137 return this->pumping;
joran 40:1668630544c7 138 }
joran 40:1668630544c7 139
sbouber1 57:8dc3192ff150 140 void PIDController::setHeating(bool enabled) {
sbouber1 35:c9261391a995 141 if(enabled == this->heating) return;
sbouber1 35:c9261391a995 142
sbouber1 35:c9261391a995 143 this->heating = enabled;
sbouber1 35:c9261391a995 144 if(enabled) {
sbouber1 57:8dc3192ff150 145 #ifdef TEST_MODE
sbouber1 35:c9261391a995 146 printf("Should set heater to 1\r\n");
sbouber1 35:c9261391a995 147 #else
sbouber1 35:c9261391a995 148 heater = 1;
sbouber1 35:c9261391a995 149 #endif
sbouber1 35:c9261391a995 150 } else {
sbouber1 57:8dc3192ff150 151 #ifdef TEST_MODE
sbouber1 35:c9261391a995 152 printf("Should set heater to 0\r\n");
sbouber1 35:c9261391a995 153 #else
sbouber1 35:c9261391a995 154 heater = 0;
sbouber1 35:c9261391a995 155 #endif
sbouber1 32:1e4919a44196 156 }
sbouber1 35:c9261391a995 157 }
sbouber1 32:1e4919a44196 158
sbouber1 32:1e4919a44196 159 float PIDController::getMlFreshWater(float ppt, float volume) {
sbouber1 32:1e4919a44196 160 return (volume * (ppt / 7.0)) - volume;
sbouber1 32:1e4919a44196 161 }
sbouber1 32:1e4919a44196 162
sbouber1 46:7e4c1f2ab76c 163 void PIDController::doTestingStuff(int ml) {
sbouber1 46:7e4c1f2ab76c 164 while(1)
sbouber1 57:8dc3192ff150 165 this->pumpSaltWater(ml);
sbouber1 46:7e4c1f2ab76c 166 }
sbouber1 46:7e4c1f2ab76c 167