De sensorcontroller van het TLS2 project.

Dependencies:   mbed

main.cpp

Committer:
RichardHoekstra
Date:
2016-11-17
Revision:
4:512492f73e90
Parent:
3:8e50fc7b82b7

File content as of revision 4:512492f73e90:

#include "mbed.h"

    enum t_sensors {sensor_pressure_1 = 0, sensor_pressure_2,
                    sensor_temperature_1, sensor_temperature_2,
                    sensor_flow} sensorRespond;
                    
//I2C settings
    #define SDA D10
    #define SCL D11
    #define sensor_addr 0x93
    #define I2C_BUFFER_SIZE 5
    I2CSlave slave(SDA,SCL);

float sensorVal[5] = {0}; //Index volgens t_sensors
#define druksensor 0
#define flowsensor 1
#define tempsensor 2


    //Sample time
    int tick_ms_druksensor1     = 10,     //100 Hz
        tick_ms_druksensor2     = 10,
        tick_ms_tempsensor1     = 1000,   //1 Hz
        tick_ms_tempsensor2     = 1000,
        tick_ms_flowsensor      = 10;     //100 Hz 

    int druksensor1_mva_elements = 10,
        druksensor2_mva_elements = 10,
        tempsensor1_mva_elements = 10,
        tempsensor2_mva_elements = 10,
        flowsensor_mva_elements = 10;

bool pressure_is_main = true; //Determine the most important sensor as in, on which value is the motor controller regulating
bool smoothing = true; //Determine to activate the moving average         

float calc_moving_average(float val, int samples = 1){
    if(samples > 1){
        static float sample_arr[100] = {0}; //[0] is the newest
        float moving_average = 0;
        if(samples > 0 && samples < 100){ //Sanity check
            //Put the new val into the sample_arr and push out the oldest one
            for(int i=samples-1; i>0; i--){
                //[9]<-[8]<-[7]
                sample_arr[i] = sample_arr[i-1];
            }
            sample_arr[0] = val;
            //Calculate the moving average
            for(int i=0; i<samples; i++){
                moving_average += sample_arr[i];
            }
            return moving_average/(float)samples;
        } else {
            return 3.1415926; //Improv error code 
        }
    } else {
        return val;    
    }
}
//Split an integer into two char
void int_to_2_char(char* arr, int val, int first_element = 0){
    arr[first_element] = val>>8;
    arr[first_element+1] = val&255;
}
//Join two char to make an integer. 
int char2_to_int(char* arr, int first_element = 0){
    return ((arr[first_element]<<8)+arr[first_element+1]);
}

//TODO: Better name, possibly consistent with the other controllers
void I2C_to_command(char* arr){
    enum command_t {    //Pressure sensor commands
                        SET_SENSOR_PRESSURE_1_SAMPLE_RATE = 13,
                        SET_SENSOR_PRESSURE_1_MVA,
                        SET_RESPONSE_SENSOR_PRESSURE_1,
                        SET_SENSOR_PRESSURE_2_SAMPLE_RATE,
                        SET_SENSOR_PRESSURE_2_MVA,
                        SET_RESPONSE_SENSOR_PRESSURE_2,
                        //Temperature sensor commands
                        SET_SENSOR_TEMPERATURE_1_SAMPLE_RATE,
                        SET_SENSOR_TEMPERATURE_1_MVA,
                        SET_RESPONSE_SENSOR_TEMPERATURE_1,
                        SET_SENSOR_TEMPERATURE_2_SAMPLE_RATE,
                        SET_SENSOR_TEMPERATURE_2_MVA,
                        SET_RESPONSE_SENSOR_TEMPERATURE_2,
                        //Flow sensor commands
                        SET_SENSOR_FLOW_SAMPLE_RATE,
                        SET_SENSOR_FLOW_MVA,
                        SET_RESPONSE_SENSOR_FLOW,
                        //Motor sensor
                        //Note: currently not used
                        SET_SENSOR_SPEED_SAMPLE_RATE,
                        SET_SENSOR_SPEED_MVA,
                        SET_RESPONSE_SENSOR_SPEED
                    } command;
                        
    command = (command_t)arr[0];
    //Hide your kids
    //Hide your wife
    //Monolithic switch statement
    //Is coming to town
    switch(command){
    //Set responses
        case SET_RESPONSE_SENSOR_PRESSURE_1:
                sensorRespond = sensor_pressure_1;
            break;
        case SET_RESPONSE_SENSOR_PRESSURE_2:
                sensorRespond = sensor_pressure_2;
            break;
        case SET_RESPONSE_SENSOR_TEMPERATURE_1:
                sensorRespond = sensor_temperature_1;
            break;
        case SET_RESPONSE_SENSOR_TEMPERATURE_2:
                sensorRespond = sensor_temperature_2;
            break;
        case SET_RESPONSE_SENSOR_FLOW:
                sensorRespond = sensor_flow;
            break;
        case SET_RESPONSE_SENSOR_SPEED:
            //Currently not implemented
            break;
            
    //Set sample rates
        case SET_SENSOR_PRESSURE_1_SAMPLE_RATE:
            tick_ms_druksensor1 = 1000/(char2_to_int(arr,1));
            break;
        case SET_SENSOR_PRESSURE_2_SAMPLE_RATE:
            tick_ms_druksensor2 = 1000/(char2_to_int(arr,1));
            break;
        case SET_SENSOR_TEMPERATURE_1_SAMPLE_RATE:
            tick_ms_tempsensor1 = 1000/(char2_to_int(arr,1));
            break;
        case SET_SENSOR_TEMPERATURE_2_SAMPLE_RATE:
            tick_ms_tempsensor2 = 1000/(char2_to_int(arr,1));
            break;
        case SET_SENSOR_FLOW_SAMPLE_RATE:
            tick_ms_flowsensor = 1000/(char2_to_int(arr,1));
            break;

    //Set moving averages
        case SET_SENSOR_PRESSURE_1_MVA:
            druksensor1_mva_elements = char2_to_int(arr,1);            
            break;
        case SET_SENSOR_PRESSURE_2_MVA:
            druksensor2_mva_elements = char2_to_int(arr,1);
            break;
        case SET_SENSOR_TEMPERATURE_1_MVA:
            tempsensor1_mva_elements = char2_to_int(arr,1);
            break;
        case SET_SENSOR_TEMPERATURE_2_MVA:
            tempsensor2_mva_elements = char2_to_int(arr,1);
            break;
        case SET_SENSOR_FLOW_MVA:
            flowsensor_mva_elements = char2_to_int(arr,1);
            break;

        default:
            //Command is not recognied
            break;                
    }
    //Clear the buffer for next iterations
    for(int i=0;i<I2C_BUFFER_SIZE;i++){
        arr[i] = 0;   
    }
}
int main() {
    //Pins
    AnalogIn    drukSensor1(A0),
                drukSensor2(A1),
                tempSensor1(A2),
                tempSensor2(A3),
                flowSensor(A4);

    //mbed ondersteund onneindig veel timers
    Timer   t_druk1,
            t_druk2,
            t_temp1,
            t_temp2,
            t_flow;
    
    //Start the timers
    t_druk1.start(); t_druk2.start(); t_temp1.start(); t_temp2.start(); t_flow.start();
    
    char buffer[I2C_BUFFER_SIZE] = {0}; //Create the buffer for I2C
    bool buffer_changed = false;
    char data[2];
    slave.address(sensor_addr);
    while(1) {
        //I2C time
        int i = slave.receive();        
        switch (i) {
            case I2CSlave::ReadAddressed:
                switch(sensorRespond){
                    case 1: //Druksensor
                        int_to_2_char(data,((int)(sensorVal[0]*65535)));
                        break;
                    case 2: //Flowsensor
                        int_to_2_char(data,((int)(sensorVal[1]*65535)));
                        break;
                    case 3://Temperatuursensor
                        int_to_2_char(data,((int)(sensorVal[2]*65535)));
                        break;                   
                }
                slave.write(data,2);
                break;
            case I2CSlave::WriteGeneral:
                //Received a request to be written to
                slave.read(buffer,I2C_BUFFER_SIZE);
                buffer_changed = true;
                break;
            case I2CSlave::WriteAddressed:
                //Received a request to be written to a specific location
                slave.read(buffer,I2C_BUFFER_SIZE);
                buffer_changed = true;
                break;
        }
        if(buffer_changed == true){
            I2C_to_command(buffer);               
        }        
        if(t_druk1.read_ms() >= tick_ms_druksensor1){
            //Lees de druksensor uit
            //TODO: Give sensorVal indices a name      
            sensorVal[0] = calc_moving_average(drukSensor1.read(), druksensor1_mva_elements);
            t_druk1.reset(); 
        }
        if(t_druk2.read_ms() >= tick_ms_druksensor2){
            //Lees de druksensor uit            
            sensorVal[1] = calc_moving_average(drukSensor2.read(), druksensor1_mva_elements);
            t_druk2.reset(); 
        }
        if(t_temp1.read_ms() >= tick_ms_tempsensor1){
            //Lees de temperatuursensor uit 
            sensorVal[2] = calc_moving_average(tempSensor1.read(),tempsensor1_mva_elements);
            t_temp1.reset();   
        }
        if(t_temp2.read_ms() >= tick_ms_tempsensor2){
            //Lees de temperatuursensor uit 
            sensorVal[3] = calc_moving_average(tempSensor2.read(),tempsensor2_mva_elements);
            t_temp2.reset();   
        }
        if(t_flow.read_ms() >= tick_ms_flowsensor){
            //Lees de flowsensor uit
            sensorVal[4] = calc_moving_average(flowSensor.read(),flowsensor_mva_elements);
            t_flow.reset();    
        }
    }
}