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

main.cpp

Committer:
sbouber1
Date:
2016-06-24
Revision:
80:38e274c4dafa
Parent:
78:a44ad011dd41

File content as of revision 80:38e274c4dafa:

#include <vector>
#include <iostream>

#include "SalinityController.h"
#include "TemperatureController.h"
#include "LCDController.h"
#include "ProximityController.h"
#include "SensorAlarmController.h"
#include "PIDController.h"
#include "settings.h"
#include "testing.h"
#include "MockSensorController.h"
#include "mbed.h"

extern int testMain();
int realMain();

int main() {
    // Either test_main() or real_main() depending on TEST_MODE define in settings.h
    return MAIN();    
}


int realMain() {
    
    
    // Collection of all controllers updated in the main loop, updated in the order they were added
    std::vector<void *> controllers;

    // -----------------------------------------------------------------------------
    /* THE FOLLOWING CONTROLLERS CAN BE THREADED BY SETTING THE FIRST ARG TO TRUE */
    /* THE SECOND ARG SPECIFIES THE DELAY AFTER EACH UPDATE, ONLY WHEN THREADED   */
    // -----------------------------------------------------------------------------
    
    TemperatureController temperature(false, 0);
    controllers.push_back((void*)&temperature);
    
    ProximityController proximity(false, 0);
    controllers.push_back((void*)&proximity);
    
    SalinityController salt(false, 0);
    controllers.push_back((void *)&salt);    
    
    // Add alarms to monitor sensor values
    SensorAlarmController temp_alarm = SensorAlarmController(false, 0, &temperature,
        TEMP_MIN_CRIT, TEMP_MIN_UNDESIRED, TEMP_MAX_CRIT, TEMP_MAX_UNDESIRED);
    temp_alarm.setUndesiredErrorMsg("Temp undes!");
    temp_alarm.setCriticalErrorMsg("Temp crit!");
    controllers.push_back((void *)&temp_alarm);

    SensorAlarmController salt_alarm = SensorAlarmController(false, 0, &salt,
        SALT_MIN_CRIT, SALT_MIN_UNDESIRED, SALT_MAX_CRIT, SALT_MAX_UNDESIRED);
    salt_alarm.setUndesiredErrorMsg("Salt undes!");
    salt_alarm.setCriticalErrorMsg("Salt crit!");
    controllers.push_back((void *)&salt_alarm);
    
    SensorAlarmController prox_alarm = SensorAlarmController(false, 0, &proximity,
        VOLUME_MIN_CRIT, VOLUME_MIN_UNDESIRED, VOLUME_MAX_CRIT, VOLUME_MAX_UNDESIRED);
    prox_alarm.setUndesiredErrorMsg("Vol undes!");
    prox_alarm.setCriticalErrorMsg("Vol crit!");
    controllers.push_back((void *)&prox_alarm);
    
    // PIDController last, as alarms should update first
    PIDController pidc(false, 0, &temperature,&salt,&proximity);
     
    // -----------------------------------------------------------------------------
    
    
    // Show the splash screen indicating the system is starting up
    LCDController::splash();    
    
    int i = 0;   
    
    // Loop forever, only breaks when an alarm triggers
    while(1) {
        
        // Wait for a specified amount of time after each iteration
        Thread::wait(MAIN_THREAD_DELAY_MS);
        
        // Iterate over all available Controllers
        vector<void *>::iterator v = controllers.begin();
        while(v != controllers.end()) {
            
            // Get the next controller
            Controller *c = ((Controller *)*v);
            
            if(!c->isThreaded())
                cout << "Running " << c->getName() << " from main loop" << "\r\n";
            
            // The controller only updates here if it's not threaded
            c->run();
            
            // Advance to the next controller
            v++;
        }
        
        // If the alarm controller detected a dangerous situation then update lcd and possibly exit
        if(temp_alarm.isError() || salt_alarm.isError() || prox_alarm.isError()) {
            
            if(temp_alarm.isError())
                LCDController::showError(temp_alarm.getErrorMessage().c_str());  
            else if(salt_alarm.isError())
                LCDController::showError(salt_alarm.getErrorMessage().c_str());  
            else
                LCDController::showError(prox_alarm.getErrorMessage().c_str()); 
            
            #ifdef HALT_ON_ALARM
            break;
            #endif
        }
        
        if(!prox_alarm.isActive()) {
            printf("Running pidcontroller!\r\n");
            pidc.run();
        } else {
            printf("Not running pidcontroller, prox alarm is active!\r\n");    
        }


        //Show temperature, salinity and volume of the water tank on the PC if connected through serial
        cout << "Temperature value: " <<  temperature.getValue() << "\r\n";
        cout << "Salinity value: " << salt.getValue() << "\r\n";
        cout << "Volume value: " << proximity.getValue() << "\r\n";

        // Show either temperature and salinity or the water level given by the proximity controller
        if(i++ % 2)
            LCDController::updateScreen(temperature.getValue(), salt.getValue(), &pidc);
        else
            LCDController::updateScreen(proximity.getValue());
        
    }

    return 1;
}