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
PIDController.cpp
- Committer:
- joran
- Date:
- 2016-06-20
- Revision:
- 63:59335eb8bdbc
- Parent:
- 62:52cceb263591
- Child:
- 65:b277b4067d4a
File content as of revision 63:59335eb8bdbc:
#include "PIDController.h" #include "testing.h" #include "LCDController.h" static DigitalOut heater(p18); static DRV8825 mtr_fresh(p21, p27, p28, p29, p22, p23); static DRV8825 mtr_salt(p24, p27, p28, p29, p25, p26); // This is called in the main loop on every iteration void PIDController::update() { #ifndef TEST_MODE if(this->num_iters < STARTUP_ITERATIONS) { printf("PIDController: not running, startup phase"); return; } #endif // Control the heater // This could be done in the pumping function as well, if needed if (this->isHeating() && this->temp->getValue() >= TEMP_MIN_UNDESIRED + 1.0f) { this->setHeating(false); } else if (!this->isHeating() && this->temp->getValue() < TEMP_MIN_UNDESIRED) { this->setHeating(true); } float s = this->salt->getValue(); float s_in_grams = this->getSaltInGrams(); if(s <= SALT_MIN_UNDESIRED) { float ml = this->getMlSaltyWater(s_in_grams, this->proximity->getValue()); int ml_int = static_cast<int>(ml); printf("PIDCONTROLLER: need to pump %d (%.3f) ml of salty water\r\n", ml_int, ml); //this->pump_salt_water(ml_int); } else if(s >= SALT_MAX_UNDESIRED) { float ml = this->getMlFreshWater(s, this->proximity->getValue()); int ml_int = static_cast<int>(ml); printf("PIDCONTROLLER: need to pump %d (%.3f) ml of fresh water\r\n", ml_int, ml); //this->pump_fresh_water(ml_int); } } std::string PIDController::getName() { return "PIDController"; } //get the salt in the body in grams float PIDController::getSaltInGrams() { float current_ppt = this->salt->getValue(); //in ppt float current_vol = this->proximity->getValue(); //in ml return current_ppt * (current_vol / 1000); } void PIDController::pumpSaltWater(int ml) { this->pumpWater(&mtr_salt, ml); } void PIDController::pumpFreshWater(int ml) { this->pumpWater(&mtr_fresh, ml); } void PIDController::pumpWater(DRV8825 *mtr, int ml) { LCDController::showPumping(); this->pumping = true; int j = 5010 * (ml - 1); for (int i = 500; i < MAX_SPEED; i += 5) { mtr->settings(1 / MICROSTEPS_PER_STEP, RIGHT, i); } for (int i = 0; i < 2010 + j; i += 1) { mtr->settings(1 / MICROSTEPS_PER_STEP, RIGHT, 8000); } for (int i = 8000; i > 500; i -= 5) { mtr->settings(1 / MICROSTEPS_PER_STEP, RIGHT, i); } wait(5); for (int i = 500; i < MAX_SPEED; i += 5) { mtr->settings(1 / MICROSTEPS_PER_STEP, LEFT, i); } for (int i = 0; i < 2010 + j; i += 1) { mtr->settings(1 / MICROSTEPS_PER_STEP, LEFT, 8000); } for (int i = 8000; i > 500; i -= 5) { mtr->settings(1 / MICROSTEPS_PER_STEP, LEFT, i); } wait(5); this->pumping = false; } float PIDController::getMlSaltyWater(float grams_in_body, float volume_in_body) { float solution_gram_per_ten = 1.16f; // 1.0f for our solution float sol_volume = 10; // 10ml float ideal_ppt_constant = 0.007f; //7 ppt / 1000 float x1 = volume_in_body * ideal_ppt_constant; float x2 = sol_volume * ideal_ppt_constant; x1 = x1 - grams_in_body; x2 = solution_gram_per_ten - x2; float output_ml = (x1 / x2 * sol_volume); return output_ml; // amount in ml to get 7 ppt. } bool PIDController::isHeating() { return this->heating; } bool PIDController::isPumping() { return this->pumping; } void PIDController::setHeating(bool enabled) { if(enabled == this->heating) return; this->heating = enabled; if(enabled) { #ifdef TEST_MODE printf("Should set heater to 1\r\n"); #else heater = 1; #endif } else { #ifdef TEST_MODE printf("Should set heater to 0\r\n"); #else heater = 0; #endif } } float PIDController::getMlFreshWater(float ppt, float volume) { return (volume * (ppt / 7.0)) - volume; } void PIDController::doTestingStuff(int ml) { while(1) this->pumpSaltWater(ml); }