Richard Hoekstra
/
TLS2-Sensorcontroller
De sensorcontroller van het TLS2 project.
main.cpp@4:512492f73e90, 2016-11-17 (annotated)
- Committer:
- RichardHoekstra
- Date:
- Thu Nov 17 12:01:21 2016 +0000
- Revision:
- 4:512492f73e90
- Parent:
- 3:8e50fc7b82b7
Load added, loads cleaned up. Can understand commands from 'hoofdcontroller' now.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
RichardHoekstra | 0:eea3cc9d2701 | 1 | #include "mbed.h" |
RichardHoekstra | 0:eea3cc9d2701 | 2 | |
RichardHoekstra | 4:512492f73e90 | 3 | enum t_sensors {sensor_pressure_1 = 0, sensor_pressure_2, |
RichardHoekstra | 4:512492f73e90 | 4 | sensor_temperature_1, sensor_temperature_2, |
RichardHoekstra | 4:512492f73e90 | 5 | sensor_flow} sensorRespond; |
RichardHoekstra | 4:512492f73e90 | 6 | |
RichardHoekstra | 3:8e50fc7b82b7 | 7 | //I2C settings |
RichardHoekstra | 3:8e50fc7b82b7 | 8 | #define SDA D10 |
RichardHoekstra | 3:8e50fc7b82b7 | 9 | #define SCL D11 |
RichardHoekstra | 3:8e50fc7b82b7 | 10 | #define sensor_addr 0x93 |
RichardHoekstra | 4:512492f73e90 | 11 | #define I2C_BUFFER_SIZE 5 |
RichardHoekstra | 3:8e50fc7b82b7 | 12 | I2CSlave slave(SDA,SCL); |
RichardHoekstra | 0:eea3cc9d2701 | 13 | |
RichardHoekstra | 4:512492f73e90 | 14 | float sensorVal[5] = {0}; //Index volgens t_sensors |
RichardHoekstra | 0:eea3cc9d2701 | 15 | #define druksensor 0 |
RichardHoekstra | 0:eea3cc9d2701 | 16 | #define flowsensor 1 |
RichardHoekstra | 1:c9fae063e6f3 | 17 | #define tempsensor 2 |
RichardHoekstra | 1:c9fae063e6f3 | 18 | |
RichardHoekstra | 4:512492f73e90 | 19 | |
RichardHoekstra | 4:512492f73e90 | 20 | //Sample time |
RichardHoekstra | 4:512492f73e90 | 21 | int tick_ms_druksensor1 = 10, //100 Hz |
RichardHoekstra | 4:512492f73e90 | 22 | tick_ms_druksensor2 = 10, |
RichardHoekstra | 4:512492f73e90 | 23 | tick_ms_tempsensor1 = 1000, //1 Hz |
RichardHoekstra | 4:512492f73e90 | 24 | tick_ms_tempsensor2 = 1000, |
RichardHoekstra | 4:512492f73e90 | 25 | tick_ms_flowsensor = 10; //100 Hz |
RichardHoekstra | 4:512492f73e90 | 26 | |
RichardHoekstra | 4:512492f73e90 | 27 | int druksensor1_mva_elements = 10, |
RichardHoekstra | 4:512492f73e90 | 28 | druksensor2_mva_elements = 10, |
RichardHoekstra | 4:512492f73e90 | 29 | tempsensor1_mva_elements = 10, |
RichardHoekstra | 4:512492f73e90 | 30 | tempsensor2_mva_elements = 10, |
RichardHoekstra | 4:512492f73e90 | 31 | flowsensor_mva_elements = 10; |
RichardHoekstra | 4:512492f73e90 | 32 | |
RichardHoekstra | 1:c9fae063e6f3 | 33 | bool pressure_is_main = true; //Determine the most important sensor as in, on which value is the motor controller regulating |
RichardHoekstra | 1:c9fae063e6f3 | 34 | bool smoothing = true; //Determine to activate the moving average |
RichardHoekstra | 1:c9fae063e6f3 | 35 | |
RichardHoekstra | 4:512492f73e90 | 36 | float calc_moving_average(float val, int samples = 1){ |
RichardHoekstra | 4:512492f73e90 | 37 | if(samples > 1){ |
RichardHoekstra | 4:512492f73e90 | 38 | static float sample_arr[100] = {0}; //[0] is the newest |
RichardHoekstra | 4:512492f73e90 | 39 | float moving_average = 0; |
RichardHoekstra | 4:512492f73e90 | 40 | if(samples > 0 && samples < 100){ //Sanity check |
RichardHoekstra | 4:512492f73e90 | 41 | //Put the new val into the sample_arr and push out the oldest one |
RichardHoekstra | 4:512492f73e90 | 42 | for(int i=samples-1; i>0; i--){ |
RichardHoekstra | 4:512492f73e90 | 43 | //[9]<-[8]<-[7] |
RichardHoekstra | 4:512492f73e90 | 44 | sample_arr[i] = sample_arr[i-1]; |
RichardHoekstra | 4:512492f73e90 | 45 | } |
RichardHoekstra | 4:512492f73e90 | 46 | sample_arr[0] = val; |
RichardHoekstra | 4:512492f73e90 | 47 | //Calculate the moving average |
RichardHoekstra | 4:512492f73e90 | 48 | for(int i=0; i<samples; i++){ |
RichardHoekstra | 4:512492f73e90 | 49 | moving_average += sample_arr[i]; |
RichardHoekstra | 4:512492f73e90 | 50 | } |
RichardHoekstra | 4:512492f73e90 | 51 | return moving_average/(float)samples; |
RichardHoekstra | 4:512492f73e90 | 52 | } else { |
RichardHoekstra | 4:512492f73e90 | 53 | return 3.1415926; //Improv error code |
RichardHoekstra | 2:4c5952cf26d0 | 54 | } |
RichardHoekstra | 2:4c5952cf26d0 | 55 | } else { |
RichardHoekstra | 4:512492f73e90 | 56 | return val; |
RichardHoekstra | 1:c9fae063e6f3 | 57 | } |
RichardHoekstra | 1:c9fae063e6f3 | 58 | } |
RichardHoekstra | 3:8e50fc7b82b7 | 59 | //Split an integer into two char |
RichardHoekstra | 3:8e50fc7b82b7 | 60 | void int_to_2_char(char* arr, int val, int first_element = 0){ |
RichardHoekstra | 3:8e50fc7b82b7 | 61 | arr[first_element] = val>>8; |
RichardHoekstra | 3:8e50fc7b82b7 | 62 | arr[first_element+1] = val&255; |
RichardHoekstra | 3:8e50fc7b82b7 | 63 | } |
RichardHoekstra | 3:8e50fc7b82b7 | 64 | //Join two char to make an integer. |
RichardHoekstra | 3:8e50fc7b82b7 | 65 | int char2_to_int(char* arr, int first_element = 0){ |
RichardHoekstra | 3:8e50fc7b82b7 | 66 | return ((arr[first_element]<<8)+arr[first_element+1]); |
RichardHoekstra | 3:8e50fc7b82b7 | 67 | } |
RichardHoekstra | 4:512492f73e90 | 68 | |
RichardHoekstra | 4:512492f73e90 | 69 | //TODO: Better name, possibly consistent with the other controllers |
RichardHoekstra | 4:512492f73e90 | 70 | void I2C_to_command(char* arr){ |
RichardHoekstra | 4:512492f73e90 | 71 | enum command_t { //Pressure sensor commands |
RichardHoekstra | 4:512492f73e90 | 72 | SET_SENSOR_PRESSURE_1_SAMPLE_RATE = 13, |
RichardHoekstra | 4:512492f73e90 | 73 | SET_SENSOR_PRESSURE_1_MVA, |
RichardHoekstra | 4:512492f73e90 | 74 | SET_RESPONSE_SENSOR_PRESSURE_1, |
RichardHoekstra | 4:512492f73e90 | 75 | SET_SENSOR_PRESSURE_2_SAMPLE_RATE, |
RichardHoekstra | 4:512492f73e90 | 76 | SET_SENSOR_PRESSURE_2_MVA, |
RichardHoekstra | 4:512492f73e90 | 77 | SET_RESPONSE_SENSOR_PRESSURE_2, |
RichardHoekstra | 4:512492f73e90 | 78 | //Temperature sensor commands |
RichardHoekstra | 4:512492f73e90 | 79 | SET_SENSOR_TEMPERATURE_1_SAMPLE_RATE, |
RichardHoekstra | 4:512492f73e90 | 80 | SET_SENSOR_TEMPERATURE_1_MVA, |
RichardHoekstra | 4:512492f73e90 | 81 | SET_RESPONSE_SENSOR_TEMPERATURE_1, |
RichardHoekstra | 4:512492f73e90 | 82 | SET_SENSOR_TEMPERATURE_2_SAMPLE_RATE, |
RichardHoekstra | 4:512492f73e90 | 83 | SET_SENSOR_TEMPERATURE_2_MVA, |
RichardHoekstra | 4:512492f73e90 | 84 | SET_RESPONSE_SENSOR_TEMPERATURE_2, |
RichardHoekstra | 4:512492f73e90 | 85 | //Flow sensor commands |
RichardHoekstra | 4:512492f73e90 | 86 | SET_SENSOR_FLOW_SAMPLE_RATE, |
RichardHoekstra | 4:512492f73e90 | 87 | SET_SENSOR_FLOW_MVA, |
RichardHoekstra | 4:512492f73e90 | 88 | SET_RESPONSE_SENSOR_FLOW, |
RichardHoekstra | 4:512492f73e90 | 89 | //Motor sensor |
RichardHoekstra | 4:512492f73e90 | 90 | //Note: currently not used |
RichardHoekstra | 4:512492f73e90 | 91 | SET_SENSOR_SPEED_SAMPLE_RATE, |
RichardHoekstra | 4:512492f73e90 | 92 | SET_SENSOR_SPEED_MVA, |
RichardHoekstra | 4:512492f73e90 | 93 | SET_RESPONSE_SENSOR_SPEED |
RichardHoekstra | 4:512492f73e90 | 94 | } command; |
RichardHoekstra | 4:512492f73e90 | 95 | |
RichardHoekstra | 4:512492f73e90 | 96 | command = (command_t)arr[0]; |
RichardHoekstra | 4:512492f73e90 | 97 | //Hide your kids |
RichardHoekstra | 4:512492f73e90 | 98 | //Hide your wife |
RichardHoekstra | 4:512492f73e90 | 99 | //Monolithic switch statement |
RichardHoekstra | 4:512492f73e90 | 100 | //Is coming to town |
RichardHoekstra | 4:512492f73e90 | 101 | switch(command){ |
RichardHoekstra | 4:512492f73e90 | 102 | //Set responses |
RichardHoekstra | 4:512492f73e90 | 103 | case SET_RESPONSE_SENSOR_PRESSURE_1: |
RichardHoekstra | 4:512492f73e90 | 104 | sensorRespond = sensor_pressure_1; |
RichardHoekstra | 4:512492f73e90 | 105 | break; |
RichardHoekstra | 4:512492f73e90 | 106 | case SET_RESPONSE_SENSOR_PRESSURE_2: |
RichardHoekstra | 4:512492f73e90 | 107 | sensorRespond = sensor_pressure_2; |
RichardHoekstra | 4:512492f73e90 | 108 | break; |
RichardHoekstra | 4:512492f73e90 | 109 | case SET_RESPONSE_SENSOR_TEMPERATURE_1: |
RichardHoekstra | 4:512492f73e90 | 110 | sensorRespond = sensor_temperature_1; |
RichardHoekstra | 4:512492f73e90 | 111 | break; |
RichardHoekstra | 4:512492f73e90 | 112 | case SET_RESPONSE_SENSOR_TEMPERATURE_2: |
RichardHoekstra | 4:512492f73e90 | 113 | sensorRespond = sensor_temperature_2; |
RichardHoekstra | 4:512492f73e90 | 114 | break; |
RichardHoekstra | 4:512492f73e90 | 115 | case SET_RESPONSE_SENSOR_FLOW: |
RichardHoekstra | 4:512492f73e90 | 116 | sensorRespond = sensor_flow; |
RichardHoekstra | 4:512492f73e90 | 117 | break; |
RichardHoekstra | 4:512492f73e90 | 118 | case SET_RESPONSE_SENSOR_SPEED: |
RichardHoekstra | 4:512492f73e90 | 119 | //Currently not implemented |
RichardHoekstra | 4:512492f73e90 | 120 | break; |
RichardHoekstra | 4:512492f73e90 | 121 | |
RichardHoekstra | 4:512492f73e90 | 122 | //Set sample rates |
RichardHoekstra | 4:512492f73e90 | 123 | case SET_SENSOR_PRESSURE_1_SAMPLE_RATE: |
RichardHoekstra | 4:512492f73e90 | 124 | tick_ms_druksensor1 = 1000/(char2_to_int(arr,1)); |
RichardHoekstra | 4:512492f73e90 | 125 | break; |
RichardHoekstra | 4:512492f73e90 | 126 | case SET_SENSOR_PRESSURE_2_SAMPLE_RATE: |
RichardHoekstra | 4:512492f73e90 | 127 | tick_ms_druksensor2 = 1000/(char2_to_int(arr,1)); |
RichardHoekstra | 4:512492f73e90 | 128 | break; |
RichardHoekstra | 4:512492f73e90 | 129 | case SET_SENSOR_TEMPERATURE_1_SAMPLE_RATE: |
RichardHoekstra | 4:512492f73e90 | 130 | tick_ms_tempsensor1 = 1000/(char2_to_int(arr,1)); |
RichardHoekstra | 4:512492f73e90 | 131 | break; |
RichardHoekstra | 4:512492f73e90 | 132 | case SET_SENSOR_TEMPERATURE_2_SAMPLE_RATE: |
RichardHoekstra | 4:512492f73e90 | 133 | tick_ms_tempsensor2 = 1000/(char2_to_int(arr,1)); |
RichardHoekstra | 4:512492f73e90 | 134 | break; |
RichardHoekstra | 4:512492f73e90 | 135 | case SET_SENSOR_FLOW_SAMPLE_RATE: |
RichardHoekstra | 4:512492f73e90 | 136 | tick_ms_flowsensor = 1000/(char2_to_int(arr,1)); |
RichardHoekstra | 4:512492f73e90 | 137 | break; |
RichardHoekstra | 4:512492f73e90 | 138 | |
RichardHoekstra | 4:512492f73e90 | 139 | //Set moving averages |
RichardHoekstra | 4:512492f73e90 | 140 | case SET_SENSOR_PRESSURE_1_MVA: |
RichardHoekstra | 4:512492f73e90 | 141 | druksensor1_mva_elements = char2_to_int(arr,1); |
RichardHoekstra | 4:512492f73e90 | 142 | break; |
RichardHoekstra | 4:512492f73e90 | 143 | case SET_SENSOR_PRESSURE_2_MVA: |
RichardHoekstra | 4:512492f73e90 | 144 | druksensor2_mva_elements = char2_to_int(arr,1); |
RichardHoekstra | 4:512492f73e90 | 145 | break; |
RichardHoekstra | 4:512492f73e90 | 146 | case SET_SENSOR_TEMPERATURE_1_MVA: |
RichardHoekstra | 4:512492f73e90 | 147 | tempsensor1_mva_elements = char2_to_int(arr,1); |
RichardHoekstra | 4:512492f73e90 | 148 | break; |
RichardHoekstra | 4:512492f73e90 | 149 | case SET_SENSOR_TEMPERATURE_2_MVA: |
RichardHoekstra | 4:512492f73e90 | 150 | tempsensor2_mva_elements = char2_to_int(arr,1); |
RichardHoekstra | 4:512492f73e90 | 151 | break; |
RichardHoekstra | 4:512492f73e90 | 152 | case SET_SENSOR_FLOW_MVA: |
RichardHoekstra | 4:512492f73e90 | 153 | flowsensor_mva_elements = char2_to_int(arr,1); |
RichardHoekstra | 4:512492f73e90 | 154 | break; |
RichardHoekstra | 4:512492f73e90 | 155 | |
RichardHoekstra | 4:512492f73e90 | 156 | default: |
RichardHoekstra | 4:512492f73e90 | 157 | //Command is not recognied |
RichardHoekstra | 4:512492f73e90 | 158 | break; |
RichardHoekstra | 4:512492f73e90 | 159 | } |
RichardHoekstra | 4:512492f73e90 | 160 | //Clear the buffer for next iterations |
RichardHoekstra | 4:512492f73e90 | 161 | for(int i=0;i<I2C_BUFFER_SIZE;i++){ |
RichardHoekstra | 4:512492f73e90 | 162 | arr[i] = 0; |
RichardHoekstra | 4:512492f73e90 | 163 | } |
RichardHoekstra | 4:512492f73e90 | 164 | } |
RichardHoekstra | 0:eea3cc9d2701 | 165 | int main() { |
RichardHoekstra | 0:eea3cc9d2701 | 166 | //Pins |
RichardHoekstra | 4:512492f73e90 | 167 | AnalogIn drukSensor1(A0), |
RichardHoekstra | 4:512492f73e90 | 168 | drukSensor2(A1), |
RichardHoekstra | 4:512492f73e90 | 169 | tempSensor1(A2), |
RichardHoekstra | 4:512492f73e90 | 170 | tempSensor2(A3), |
RichardHoekstra | 4:512492f73e90 | 171 | flowSensor(A4); |
RichardHoekstra | 0:eea3cc9d2701 | 172 | |
RichardHoekstra | 0:eea3cc9d2701 | 173 | //mbed ondersteund onneindig veel timers |
RichardHoekstra | 4:512492f73e90 | 174 | Timer t_druk1, |
RichardHoekstra | 4:512492f73e90 | 175 | t_druk2, |
RichardHoekstra | 4:512492f73e90 | 176 | t_temp1, |
RichardHoekstra | 4:512492f73e90 | 177 | t_temp2, |
RichardHoekstra | 4:512492f73e90 | 178 | t_flow; |
RichardHoekstra | 4:512492f73e90 | 179 | |
RichardHoekstra | 4:512492f73e90 | 180 | //Start the timers |
RichardHoekstra | 4:512492f73e90 | 181 | t_druk1.start(); t_druk2.start(); t_temp1.start(); t_temp2.start(); t_flow.start(); |
RichardHoekstra | 4:512492f73e90 | 182 | |
RichardHoekstra | 3:8e50fc7b82b7 | 183 | char buffer[I2C_BUFFER_SIZE] = {0}; //Create the buffer for I2C |
RichardHoekstra | 3:8e50fc7b82b7 | 184 | bool buffer_changed = false; |
RichardHoekstra | 3:8e50fc7b82b7 | 185 | char data[2]; |
RichardHoekstra | 3:8e50fc7b82b7 | 186 | slave.address(sensor_addr); |
RichardHoekstra | 0:eea3cc9d2701 | 187 | while(1) { |
RichardHoekstra | 3:8e50fc7b82b7 | 188 | //I2C time |
RichardHoekstra | 3:8e50fc7b82b7 | 189 | int i = slave.receive(); |
RichardHoekstra | 3:8e50fc7b82b7 | 190 | switch (i) { |
RichardHoekstra | 3:8e50fc7b82b7 | 191 | case I2CSlave::ReadAddressed: |
RichardHoekstra | 4:512492f73e90 | 192 | switch(sensorRespond){ |
RichardHoekstra | 3:8e50fc7b82b7 | 193 | case 1: //Druksensor |
RichardHoekstra | 3:8e50fc7b82b7 | 194 | int_to_2_char(data,((int)(sensorVal[0]*65535))); |
RichardHoekstra | 3:8e50fc7b82b7 | 195 | break; |
RichardHoekstra | 3:8e50fc7b82b7 | 196 | case 2: //Flowsensor |
RichardHoekstra | 3:8e50fc7b82b7 | 197 | int_to_2_char(data,((int)(sensorVal[1]*65535))); |
RichardHoekstra | 3:8e50fc7b82b7 | 198 | break; |
RichardHoekstra | 3:8e50fc7b82b7 | 199 | case 3://Temperatuursensor |
RichardHoekstra | 3:8e50fc7b82b7 | 200 | int_to_2_char(data,((int)(sensorVal[2]*65535))); |
RichardHoekstra | 3:8e50fc7b82b7 | 201 | break; |
RichardHoekstra | 3:8e50fc7b82b7 | 202 | } |
RichardHoekstra | 3:8e50fc7b82b7 | 203 | slave.write(data,2); |
RichardHoekstra | 3:8e50fc7b82b7 | 204 | break; |
RichardHoekstra | 3:8e50fc7b82b7 | 205 | case I2CSlave::WriteGeneral: |
RichardHoekstra | 3:8e50fc7b82b7 | 206 | //Received a request to be written to |
RichardHoekstra | 3:8e50fc7b82b7 | 207 | slave.read(buffer,I2C_BUFFER_SIZE); |
RichardHoekstra | 3:8e50fc7b82b7 | 208 | buffer_changed = true; |
RichardHoekstra | 3:8e50fc7b82b7 | 209 | break; |
RichardHoekstra | 3:8e50fc7b82b7 | 210 | case I2CSlave::WriteAddressed: |
RichardHoekstra | 3:8e50fc7b82b7 | 211 | //Received a request to be written to a specific location |
RichardHoekstra | 3:8e50fc7b82b7 | 212 | slave.read(buffer,I2C_BUFFER_SIZE); |
RichardHoekstra | 3:8e50fc7b82b7 | 213 | buffer_changed = true; |
RichardHoekstra | 3:8e50fc7b82b7 | 214 | break; |
RichardHoekstra | 3:8e50fc7b82b7 | 215 | } |
RichardHoekstra | 3:8e50fc7b82b7 | 216 | if(buffer_changed == true){ |
RichardHoekstra | 4:512492f73e90 | 217 | I2C_to_command(buffer); |
RichardHoekstra | 3:8e50fc7b82b7 | 218 | } |
RichardHoekstra | 4:512492f73e90 | 219 | if(t_druk1.read_ms() >= tick_ms_druksensor1){ |
RichardHoekstra | 4:512492f73e90 | 220 | //Lees de druksensor uit |
RichardHoekstra | 4:512492f73e90 | 221 | //TODO: Give sensorVal indices a name |
RichardHoekstra | 4:512492f73e90 | 222 | sensorVal[0] = calc_moving_average(drukSensor1.read(), druksensor1_mva_elements); |
RichardHoekstra | 4:512492f73e90 | 223 | t_druk1.reset(); |
RichardHoekstra | 4:512492f73e90 | 224 | } |
RichardHoekstra | 4:512492f73e90 | 225 | if(t_druk2.read_ms() >= tick_ms_druksensor2){ |
RichardHoekstra | 1:c9fae063e6f3 | 226 | //Lees de druksensor uit |
RichardHoekstra | 4:512492f73e90 | 227 | sensorVal[1] = calc_moving_average(drukSensor2.read(), druksensor1_mva_elements); |
RichardHoekstra | 4:512492f73e90 | 228 | t_druk2.reset(); |
RichardHoekstra | 4:512492f73e90 | 229 | } |
RichardHoekstra | 4:512492f73e90 | 230 | if(t_temp1.read_ms() >= tick_ms_tempsensor1){ |
RichardHoekstra | 4:512492f73e90 | 231 | //Lees de temperatuursensor uit |
RichardHoekstra | 4:512492f73e90 | 232 | sensorVal[2] = calc_moving_average(tempSensor1.read(),tempsensor1_mva_elements); |
RichardHoekstra | 4:512492f73e90 | 233 | t_temp1.reset(); |
RichardHoekstra | 4:512492f73e90 | 234 | } |
RichardHoekstra | 4:512492f73e90 | 235 | if(t_temp2.read_ms() >= tick_ms_tempsensor2){ |
RichardHoekstra | 4:512492f73e90 | 236 | //Lees de temperatuursensor uit |
RichardHoekstra | 4:512492f73e90 | 237 | sensorVal[3] = calc_moving_average(tempSensor2.read(),tempsensor2_mva_elements); |
RichardHoekstra | 4:512492f73e90 | 238 | t_temp2.reset(); |
RichardHoekstra | 0:eea3cc9d2701 | 239 | } |
RichardHoekstra | 0:eea3cc9d2701 | 240 | if(t_flow.read_ms() >= tick_ms_flowsensor){ |
RichardHoekstra | 0:eea3cc9d2701 | 241 | //Lees de flowsensor uit |
RichardHoekstra | 4:512492f73e90 | 242 | sensorVal[4] = calc_moving_average(flowSensor.read(),flowsensor_mva_elements); |
RichardHoekstra | 0:eea3cc9d2701 | 243 | t_flow.reset(); |
RichardHoekstra | 0:eea3cc9d2701 | 244 | } |
RichardHoekstra | 0:eea3cc9d2701 | 245 | } |
RichardHoekstra | 0:eea3cc9d2701 | 246 | } |