Richard Hoekstra
/
TLS2-Sensorcontroller
De sensorcontroller van het TLS2 project.
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(); } } }