SysBee v1
Dependencies: C027_Support mbed
Fork of App_Pese_Ruche_SYSBEE by
main.cpp@5:d2702cbe5afe, 2018-09-06 (annotated)
- Committer:
- thomaspotier
- Date:
- Thu Sep 06 14:40:02 2018 +0000
- Revision:
- 5:d2702cbe5afe
- Parent:
- 4:bee94a4094b6
- Child:
- 6:b69c4870db2c
Adding state machine
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bennettmatt1977 | 0:15a06b50e14e | 1 | #include "mbed.h" |
maxelior | 1:5639bc1208d5 | 2 | #include <string.h> |
thomaspotier | 5:d2702cbe5afe | 3 | //#include <LowPowerTimeout.h> |
bennettmatt1977 | 0:15a06b50e14e | 4 | |
bennettmatt1977 | 0:15a06b50e14e | 5 | #include "GPS.h" |
bennettmatt1977 | 0:15a06b50e14e | 6 | #include "MDM.h" |
thomaspotier | 4:bee94a4094b6 | 7 | |
thomaspotier | 4:bee94a4094b6 | 8 | // sim pin code |
maxelior | 1:5639bc1208d5 | 9 | #define SIMPIN "1234" |
bennettmatt1977 | 0:15a06b50e14e | 10 | #define APN NULL |
bennettmatt1977 | 0:15a06b50e14e | 11 | #define USERNAME NULL |
maxelior | 1:5639bc1208d5 | 12 | #define PASSWORD NULL |
maxelior | 2:57d040afa937 | 13 | |
thomaspotier | 4:bee94a4094b6 | 14 | // size of the average buffer (more means more averaged) |
thomaspotier | 5:d2702cbe5afe | 15 | #define AVERAGING_SIZE 500 |
thomaspotier | 4:bee94a4094b6 | 16 | // time between each capture in us |
thomaspotier | 5:d2702cbe5afe | 17 | #define AVERAGING_TIME 500 |
maxelior | 2:57d040afa937 | 18 | |
thomaspotier | 4:bee94a4094b6 | 19 | // time between each mesures in s |
thomaspotier | 5:d2702cbe5afe | 20 | #define MEASURE_INTERVAL 5 //(10 * 60) |
thomaspotier | 5:d2702cbe5afe | 21 | // time between each averaging in s |
thomaspotier | 5:d2702cbe5afe | 22 | #define AVERAGE_INTERVAL 20 //(24 * 60 * 60) |
thomaspotier | 5:d2702cbe5afe | 23 | // number of measure before average |
thomaspotier | 5:d2702cbe5afe | 24 | #define AVERAGE_COUNT ((int)(AVERAGE_INTERVAL / MEASURE_INTERVAL)) |
thomaspotier | 4:bee94a4094b6 | 25 | |
thomaspotier | 4:bee94a4094b6 | 26 | #define SENSOR_OFFSET 6.1f |
thomaspotier | 4:bee94a4094b6 | 27 | #define SENSOR_FACTOR 39.0f |
thomaspotier | 4:bee94a4094b6 | 28 | |
thomaspotier | 4:bee94a4094b6 | 29 | // weight difference needed to send sms |
thomaspotier | 4:bee94a4094b6 | 30 | #define DIFF_THRESHOLD 0.4f |
maxelior | 3:8b90a40df4db | 31 | |
thomaspotier | 4:bee94a4094b6 | 32 | // states of the hive |
thomaspotier | 4:bee94a4094b6 | 33 | typedef enum E_HIVE_STATE { |
thomaspotier | 5:d2702cbe5afe | 34 | HIVE_STATE_INIT = 0, |
thomaspotier | 5:d2702cbe5afe | 35 | HIVE_STATE_AVERAGE, |
thomaspotier | 5:d2702cbe5afe | 36 | HIVE_STATE_MEASURE, |
thomaspotier | 5:d2702cbe5afe | 37 | HIVE_STATE_NOTHING_NEW, |
thomaspotier | 5:d2702cbe5afe | 38 | HIVE_STATE_HONEY, |
thomaspotier | 5:d2702cbe5afe | 39 | HIVE_STATE_PROBLEM, |
thomaspotier | 5:d2702cbe5afe | 40 | HIVE_STATE_PROBLEM_SPRING, |
thomaspotier | 5:d2702cbe5afe | 41 | HIVE_STATE_MSG |
thomaspotier | 4:bee94a4094b6 | 42 | } t_hive_state; |
maxelior | 3:8b90a40df4db | 43 | |
thomaspotier | 5:d2702cbe5afe | 44 | t_hive_state current_state = HIVE_STATE_INIT; |
thomaspotier | 4:bee94a4094b6 | 45 | |
thomaspotier | 4:bee94a4094b6 | 46 | // buffer used to create message content |
thomaspotier | 4:bee94a4094b6 | 47 | char buffer[1024]; |
maxelior | 3:8b90a40df4db | 48 | |
thomaspotier | 5:d2702cbe5afe | 49 | float average_values[AVERAGE_COUNT] = {0.0f}; |
thomaspotier | 5:d2702cbe5afe | 50 | float last_average = 0; |
thomaspotier | 5:d2702cbe5afe | 51 | float current_average = 0; |
thomaspotier | 5:d2702cbe5afe | 52 | float current_average_diff = 0; |
thomaspotier | 5:d2702cbe5afe | 53 | float current_measure_diff = 0; |
thomaspotier | 5:d2702cbe5afe | 54 | unsigned int average_ticks_passed = 0; |
thomaspotier | 4:bee94a4094b6 | 55 | |
thomaspotier | 4:bee94a4094b6 | 56 | // analog read of sensor board output |
thomaspotier | 4:bee94a4094b6 | 57 | AnalogIn sensor(PC_5); |
thomaspotier | 4:bee94a4094b6 | 58 | |
thomaspotier | 4:bee94a4094b6 | 59 | // phone number for sms (Cosima DORLAND) |
thomaspotier | 5:d2702cbe5afe | 60 | //const char phone_number[] = "0783099416"; |
thomaspotier | 5:d2702cbe5afe | 61 | const char phone_number[] = "0786074814"; |
thomaspotier | 4:bee94a4094b6 | 62 | |
thomaspotier | 4:bee94a4094b6 | 63 | // Serial object for pc communications |
thomaspotier | 4:bee94a4094b6 | 64 | Serial pc(USBTX, USBRX); |
maxelior | 1:5639bc1208d5 | 65 | |
thomaspotier | 4:bee94a4094b6 | 66 | // modem object for sms communications |
thomaspotier | 4:bee94a4094b6 | 67 | MDMSerial modem; |
thomaspotier | 4:bee94a4094b6 | 68 | |
thomaspotier | 5:d2702cbe5afe | 69 | // sleep utils |
thomaspotier | 5:d2702cbe5afe | 70 | Timeout sleep_timout; |
thomaspotier | 5:d2702cbe5afe | 71 | |
thomaspotier | 5:d2702cbe5afe | 72 | bool awake = true; |
thomaspotier | 5:d2702cbe5afe | 73 | |
thomaspotier | 4:bee94a4094b6 | 74 | // led for test blink |
thomaspotier | 4:bee94a4094b6 | 75 | DigitalOut led(LED1); |
thomaspotier | 4:bee94a4094b6 | 76 | |
thomaspotier | 4:bee94a4094b6 | 77 | |
thomaspotier | 5:d2702cbe5afe | 78 | void blink(void) |
thomaspotier | 4:bee94a4094b6 | 79 | { |
thomaspotier | 4:bee94a4094b6 | 80 | led.write(1); |
thomaspotier | 4:bee94a4094b6 | 81 | wait(0.2); |
thomaspotier | 4:bee94a4094b6 | 82 | led.write(0); |
maxelior | 2:57d040afa937 | 83 | } |
maxelior | 1:5639bc1208d5 | 84 | |
thomaspotier | 5:d2702cbe5afe | 85 | void wake_up(void) |
thomaspotier | 5:d2702cbe5afe | 86 | { |
thomaspotier | 5:d2702cbe5afe | 87 | awake = true; |
thomaspotier | 5:d2702cbe5afe | 88 | } |
thomaspotier | 5:d2702cbe5afe | 89 | |
thomaspotier | 5:d2702cbe5afe | 90 | void power_sleep(float time) |
thomaspotier | 5:d2702cbe5afe | 91 | { |
thomaspotier | 5:d2702cbe5afe | 92 | awake = false; |
thomaspotier | 5:d2702cbe5afe | 93 | sleep_timout.attach(wake_up, time); |
thomaspotier | 5:d2702cbe5afe | 94 | pc.printf("Going to sleep !\n\r"); |
thomaspotier | 5:d2702cbe5afe | 95 | while (!awake) sleep(); |
thomaspotier | 5:d2702cbe5afe | 96 | pc.printf("Woke up !\n\r"); |
thomaspotier | 5:d2702cbe5afe | 97 | } |
thomaspotier | 5:d2702cbe5afe | 98 | |
thomaspotier | 4:bee94a4094b6 | 99 | // send a sms to the phone number |
thomaspotier | 4:bee94a4094b6 | 100 | void send_message(char msg[]) |
thomaspotier | 4:bee94a4094b6 | 101 | { |
thomaspotier | 4:bee94a4094b6 | 102 | MDMParser::DevStatus devStatus = {}; |
thomaspotier | 4:bee94a4094b6 | 103 | MDMParser::NetStatus netStatus = {}; |
maxelior | 2:57d040afa937 | 104 | |
thomaspotier | 4:bee94a4094b6 | 105 | // log sms sending to pc |
thomaspotier | 5:d2702cbe5afe | 106 | pc.printf("\x1b[34mSMS: %s\n\r\x1b[0m", msg); |
thomaspotier | 4:bee94a4094b6 | 107 | |
thomaspotier | 4:bee94a4094b6 | 108 | while (!modem.checkNetStatus(&netStatus)) { |
thomaspotier | 5:d2702cbe5afe | 109 | pc.printf("\x1b[34mMODEM checkNetStatus failed...\n\r\x1b[0m"); |
thomaspotier | 4:bee94a4094b6 | 110 | wait(1); |
thomaspotier | 4:bee94a4094b6 | 111 | } |
thomaspotier | 4:bee94a4094b6 | 112 | modem.dumpDevStatus(&devStatus); |
thomaspotier | 4:bee94a4094b6 | 113 | while (!modem.registerNet(&netStatus)) { |
thomaspotier | 5:d2702cbe5afe | 114 | pc.printf("\x1b[34mMODEM registerNet failed...\n\r\x1b[0m"); |
thomaspotier | 4:bee94a4094b6 | 115 | wait(1); |
thomaspotier | 4:bee94a4094b6 | 116 | } |
thomaspotier | 4:bee94a4094b6 | 117 | modem.dumpNetStatus(&netStatus); |
thomaspotier | 4:bee94a4094b6 | 118 | modem.smsSend(phone_number ,msg); |
maxelior | 2:57d040afa937 | 119 | } |
maxelior | 1:5639bc1208d5 | 120 | |
thomaspotier | 4:bee94a4094b6 | 121 | // return the current calibrated weight |
thomaspotier | 4:bee94a4094b6 | 122 | float get_weight() |
thomaspotier | 4:bee94a4094b6 | 123 | { |
thomaspotier | 4:bee94a4094b6 | 124 | float weight; |
thomaspotier | 4:bee94a4094b6 | 125 | |
thomaspotier | 4:bee94a4094b6 | 126 | // weight is the sensor output in volts |
thomaspotier | 4:bee94a4094b6 | 127 | weight = sensor.read() * 3.3f; |
thomaspotier | 4:bee94a4094b6 | 128 | // return calibrated result |
thomaspotier | 4:bee94a4094b6 | 129 | return (weight * SENSOR_FACTOR - SENSOR_OFFSET); |
thomaspotier | 4:bee94a4094b6 | 130 | } |
thomaspotier | 4:bee94a4094b6 | 131 | |
thomaspotier | 4:bee94a4094b6 | 132 | // return an averaged weight (time consuming function) |
thomaspotier | 4:bee94a4094b6 | 133 | float get_averaged_weight() |
thomaspotier | 4:bee94a4094b6 | 134 | { |
thomaspotier | 4:bee94a4094b6 | 135 | float average = 0; |
thomaspotier | 4:bee94a4094b6 | 136 | int i; |
thomaspotier | 4:bee94a4094b6 | 137 | |
thomaspotier | 4:bee94a4094b6 | 138 | for(i = 0; i < AVERAGING_SIZE; i++) { |
thomaspotier | 4:bee94a4094b6 | 139 | average += get_weight(); |
thomaspotier | 4:bee94a4094b6 | 140 | wait_us(AVERAGING_TIME); |
thomaspotier | 4:bee94a4094b6 | 141 | } |
thomaspotier | 4:bee94a4094b6 | 142 | return (average / AVERAGING_SIZE); |
thomaspotier | 4:bee94a4094b6 | 143 | } |
thomaspotier | 4:bee94a4094b6 | 144 | |
thomaspotier | 4:bee94a4094b6 | 145 | // automata calculations |
maxelior | 1:5639bc1208d5 | 146 | void automate() |
maxelior | 1:5639bc1208d5 | 147 | { |
thomaspotier | 4:bee94a4094b6 | 148 | switch(current_state) { |
thomaspotier | 5:d2702cbe5afe | 149 | case HIVE_STATE_INIT: |
thomaspotier | 5:d2702cbe5afe | 150 | if (average_ticks_passed == AVERAGE_COUNT) |
thomaspotier | 5:d2702cbe5afe | 151 | current_state = HIVE_STATE_AVERAGE; |
thomaspotier | 5:d2702cbe5afe | 152 | else |
thomaspotier | 5:d2702cbe5afe | 153 | current_state = HIVE_STATE_MEASURE; |
thomaspotier | 5:d2702cbe5afe | 154 | power_sleep(MEASURE_INTERVAL); |
thomaspotier | 5:d2702cbe5afe | 155 | break; |
thomaspotier | 5:d2702cbe5afe | 156 | case HIVE_STATE_MEASURE: |
thomaspotier | 5:d2702cbe5afe | 157 | average_values[average_ticks_passed] = get_averaged_weight(); |
thomaspotier | 5:d2702cbe5afe | 158 | pc.printf("Weight is %02.2fkg\n\r", average_values[average_ticks_passed]); |
thomaspotier | 5:d2702cbe5afe | 159 | // if we are of the first measure use the one at the end of the list (last one) |
thomaspotier | 5:d2702cbe5afe | 160 | current_measure_diff = average_ticks_passed == 0 ? average_values[average_ticks_passed] - average_values[AVERAGE_COUNT - 1] : average_values[average_ticks_passed] - average_values[average_ticks_passed - 1]; |
thomaspotier | 5:d2702cbe5afe | 161 | if (abs(current_measure_diff) > DIFF_THRESHOLD) |
thomaspotier | 5:d2702cbe5afe | 162 | current_state = HIVE_STATE_PROBLEM; |
thomaspotier | 5:d2702cbe5afe | 163 | else |
thomaspotier | 5:d2702cbe5afe | 164 | current_state = HIVE_STATE_INIT; |
thomaspotier | 5:d2702cbe5afe | 165 | average_ticks_passed++; |
thomaspotier | 5:d2702cbe5afe | 166 | break; |
thomaspotier | 5:d2702cbe5afe | 167 | case HIVE_STATE_AVERAGE: |
thomaspotier | 5:d2702cbe5afe | 168 | current_average = 0; |
thomaspotier | 5:d2702cbe5afe | 169 | for(int i = 0; i < average_ticks_passed; i++) { |
thomaspotier | 5:d2702cbe5afe | 170 | current_average += average_values[i]; |
maxelior | 1:5639bc1208d5 | 171 | } |
thomaspotier | 5:d2702cbe5afe | 172 | current_average /= average_ticks_passed; |
thomaspotier | 5:d2702cbe5afe | 173 | current_average_diff = current_average - last_average; |
thomaspotier | 5:d2702cbe5afe | 174 | last_average = current_average; |
thomaspotier | 5:d2702cbe5afe | 175 | if (abs(current_average_diff) > DIFF_THRESHOLD) |
thomaspotier | 5:d2702cbe5afe | 176 | current_state = HIVE_STATE_HONEY; |
thomaspotier | 5:d2702cbe5afe | 177 | else |
thomaspotier | 5:d2702cbe5afe | 178 | current_state = HIVE_STATE_NOTHING_NEW; |
thomaspotier | 5:d2702cbe5afe | 179 | average_ticks_passed = 0; |
thomaspotier | 5:d2702cbe5afe | 180 | break; |
thomaspotier | 5:d2702cbe5afe | 181 | case HIVE_STATE_PROBLEM: |
thomaspotier | 5:d2702cbe5afe | 182 | sprintf(buffer, "There has been a problem : %0.1fkg of change in %d minutes !", current_measure_diff, MEASURE_INTERVAL / 60); |
thomaspotier | 5:d2702cbe5afe | 183 | current_state = HIVE_STATE_MSG; |
thomaspotier | 5:d2702cbe5afe | 184 | break; |
thomaspotier | 5:d2702cbe5afe | 185 | case HIVE_STATE_HONEY: |
thomaspotier | 5:d2702cbe5afe | 186 | sprintf(buffer, "There is more and more honey in the hive ! %0.1fkg of change in %d hours !", current_average_diff, AVERAGE_INTERVAL / 60); |
thomaspotier | 5:d2702cbe5afe | 187 | current_state = HIVE_STATE_MSG; |
thomaspotier | 5:d2702cbe5afe | 188 | break; |
thomaspotier | 5:d2702cbe5afe | 189 | case HIVE_STATE_NOTHING_NEW: |
thomaspotier | 5:d2702cbe5afe | 190 | sprintf(buffer, "Everything is fine ! %0.1fkg of change in %d hours !", current_average_diff, AVERAGE_INTERVAL / 60); |
thomaspotier | 5:d2702cbe5afe | 191 | current_state = HIVE_STATE_MSG; |
thomaspotier | 5:d2702cbe5afe | 192 | break; |
thomaspotier | 5:d2702cbe5afe | 193 | case HIVE_STATE_MSG: |
thomaspotier | 5:d2702cbe5afe | 194 | send_message(buffer); |
thomaspotier | 5:d2702cbe5afe | 195 | current_state = HIVE_STATE_INIT; |
maxelior | 1:5639bc1208d5 | 196 | break; |
thomaspotier | 4:bee94a4094b6 | 197 | default: |
thomaspotier | 5:d2702cbe5afe | 198 | pc.printf("Error..."); |
maxelior | 2:57d040afa937 | 199 | break; |
maxelior | 1:5639bc1208d5 | 200 | } |
maxelior | 1:5639bc1208d5 | 201 | } |
bennettmatt1977 | 0:15a06b50e14e | 202 | |
thomaspotier | 4:bee94a4094b6 | 203 | void init_modem(void) |
thomaspotier | 4:bee94a4094b6 | 204 | { |
thomaspotier | 4:bee94a4094b6 | 205 | MDMParser::DevStatus devStatus = {}; |
thomaspotier | 4:bee94a4094b6 | 206 | MDMParser::NetStatus netStatus = {}; |
thomaspotier | 4:bee94a4094b6 | 207 | |
thomaspotier | 4:bee94a4094b6 | 208 | // retry from begining if something fails |
thomaspotier | 4:bee94a4094b6 | 209 | while (!modem.init(SIMPIN, &devStatus, D4)) { |
thomaspotier | 4:bee94a4094b6 | 210 | pc.printf("\x1b[34m"); |
thomaspotier | 4:bee94a4094b6 | 211 | pc.printf("MODEM init failed...\n\r"); |
thomaspotier | 4:bee94a4094b6 | 212 | pc.printf("\x1b[0m"); |
thomaspotier | 4:bee94a4094b6 | 213 | wait(1); |
thomaspotier | 4:bee94a4094b6 | 214 | } |
thomaspotier | 4:bee94a4094b6 | 215 | while (!modem.checkNetStatus(&netStatus)) { |
thomaspotier | 4:bee94a4094b6 | 216 | pc.printf("\x1b[34m"); |
thomaspotier | 4:bee94a4094b6 | 217 | pc.printf("MODEM net_status failed...\n\r"); |
thomaspotier | 4:bee94a4094b6 | 218 | pc.printf("\x1b[0m"); |
thomaspotier | 4:bee94a4094b6 | 219 | wait(1); |
thomaspotier | 4:bee94a4094b6 | 220 | } |
thomaspotier | 4:bee94a4094b6 | 221 | modem.dumpDevStatus(&devStatus); |
thomaspotier | 4:bee94a4094b6 | 222 | } |
thomaspotier | 4:bee94a4094b6 | 223 | |
bennettmatt1977 | 0:15a06b50e14e | 224 | int main(void) |
bennettmatt1977 | 0:15a06b50e14e | 225 | { |
thomaspotier | 4:bee94a4094b6 | 226 | // setting baud rate for serial communication with the pc |
maxelior | 1:5639bc1208d5 | 227 | pc.baud(115200); |
thomaspotier | 4:bee94a4094b6 | 228 | pc.printf("TEST\n\r"); |
thomaspotier | 4:bee94a4094b6 | 229 | init_modem(); |
thomaspotier | 4:bee94a4094b6 | 230 | |
thomaspotier | 4:bee94a4094b6 | 231 | // main loop |
maxelior | 1:5639bc1208d5 | 232 | while(1) { |
thomaspotier | 4:bee94a4094b6 | 233 | // blink once for each measure |
thomaspotier | 5:d2702cbe5afe | 234 | //blink(); |
thomaspotier | 4:bee94a4094b6 | 235 | // getting sensor values |
thomaspotier | 4:bee94a4094b6 | 236 | // acquisition(); |
thomaspotier | 4:bee94a4094b6 | 237 | // changing state of automata according to read values |
maxelior | 1:5639bc1208d5 | 238 | automate(); |
bennettmatt1977 | 0:15a06b50e14e | 239 | } |
bennettmatt1977 | 0:15a06b50e14e | 240 | } |
maxelior | 1:5639bc1208d5 | 241 | |
maxelior | 1:5639bc1208d5 | 242 | |
maxelior | 1:5639bc1208d5 | 243 | |
maxelior | 1:5639bc1208d5 | 244 | |
maxelior | 1:5639bc1208d5 | 245 |