SysBee v1

Dependencies:   C027_Support mbed

Fork of App_Pese_Ruche_SYSBEE by Sysbee

main.cpp

Committer:
thomaspotier
Date:
2018-09-06
Revision:
5:d2702cbe5afe
Parent:
4:bee94a4094b6
Child:
6:b69c4870db2c

File content as of revision 5:d2702cbe5afe:

#include "mbed.h"
#include <string.h>
//#include <LowPowerTimeout.h>

#include "GPS.h"
#include "MDM.h"

// sim pin code
#define SIMPIN      "1234"
#define APN         NULL
#define USERNAME    NULL
#define PASSWORD    NULL

// size of the average buffer (more means more averaged)
#define AVERAGING_SIZE      500
// time between each capture in us
#define AVERAGING_TIME      500

// time between each mesures in s
#define MEASURE_INTERVAL    5 //(10 * 60)
// time between each averaging in s
#define AVERAGE_INTERVAL    20 //(24 * 60 * 60)
// number of measure before average
#define AVERAGE_COUNT       ((int)(AVERAGE_INTERVAL / MEASURE_INTERVAL))

#define SENSOR_OFFSET       6.1f
#define SENSOR_FACTOR       39.0f

// weight difference needed to send sms
#define DIFF_THRESHOLD       0.4f

// states of the hive
typedef enum    E_HIVE_STATE {
    HIVE_STATE_INIT = 0,
    HIVE_STATE_AVERAGE,
    HIVE_STATE_MEASURE,
    HIVE_STATE_NOTHING_NEW,
    HIVE_STATE_HONEY,
    HIVE_STATE_PROBLEM,
    HIVE_STATE_PROBLEM_SPRING,
    HIVE_STATE_MSG
}               t_hive_state;

t_hive_state current_state = HIVE_STATE_INIT;

// buffer used to create message content
char buffer[1024];

float average_values[AVERAGE_COUNT] = {0.0f};
float last_average = 0;
float current_average = 0;
float current_average_diff = 0;
float current_measure_diff = 0;
unsigned int average_ticks_passed = 0;

// analog read of sensor board output
AnalogIn sensor(PC_5);

// phone number for sms (Cosima DORLAND)
//const char phone_number[] = "0783099416";
const char phone_number[] = "0786074814";

// Serial object for pc communications
Serial pc(USBTX, USBRX);

// modem object for sms communications
MDMSerial modem;

// sleep utils
Timeout sleep_timout;

bool awake = true;
 
// led for test blink
DigitalOut led(LED1);


void blink(void)
{
    led.write(1);
    wait(0.2);
    led.write(0);
}

void wake_up(void)
{
    awake = true;
}

void power_sleep(float time)
{
    awake = false;
    sleep_timout.attach(wake_up, time);
    pc.printf("Going to sleep !\n\r");
    while (!awake) sleep();
    pc.printf("Woke up !\n\r");
}

// send a sms to the phone number
void send_message(char msg[])
{
    MDMParser::DevStatus devStatus = {};
    MDMParser::NetStatus netStatus = {};

    // log sms sending to pc
    pc.printf("\x1b[34mSMS: %s\n\r\x1b[0m", msg);
    
    while (!modem.checkNetStatus(&netStatus)) {
        pc.printf("\x1b[34mMODEM checkNetStatus failed...\n\r\x1b[0m");
        wait(1);
    }
    modem.dumpDevStatus(&devStatus);
    while (!modem.registerNet(&netStatus)) {
        pc.printf("\x1b[34mMODEM registerNet failed...\n\r\x1b[0m");
        wait(1);
    }
    modem.dumpNetStatus(&netStatus);
    modem.smsSend(phone_number ,msg);
}

// return the current calibrated weight
float get_weight()
{
    float weight;

    // weight is the sensor output in volts
    weight = sensor.read() * 3.3f;
    // return calibrated result
    return (weight * SENSOR_FACTOR - SENSOR_OFFSET);
}

// return an averaged weight (time consuming function)
float get_averaged_weight()
{
    float average = 0;
    int i;

    for(i = 0; i < AVERAGING_SIZE; i++) {
        average += get_weight();
        wait_us(AVERAGING_TIME);
    }
    return (average / AVERAGING_SIZE);
}

// automata calculations
void automate()
{
    switch(current_state) {
        case HIVE_STATE_INIT:
            if (average_ticks_passed == AVERAGE_COUNT)
                current_state = HIVE_STATE_AVERAGE;
            else
                current_state = HIVE_STATE_MEASURE;
            power_sleep(MEASURE_INTERVAL);
            break;
        case HIVE_STATE_MEASURE:
            average_values[average_ticks_passed] = get_averaged_weight();
            pc.printf("Weight is %02.2fkg\n\r", average_values[average_ticks_passed]);
            // if we are of the first measure use the one at the end of the list (last one)
            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];
            if (abs(current_measure_diff) > DIFF_THRESHOLD)
                current_state = HIVE_STATE_PROBLEM;
            else
                current_state = HIVE_STATE_INIT;
            average_ticks_passed++;
            break;
        case HIVE_STATE_AVERAGE:
            current_average = 0;
            for(int i = 0; i < average_ticks_passed; i++) {
                current_average += average_values[i];
            }
            current_average /= average_ticks_passed;
            current_average_diff = current_average - last_average;
            last_average = current_average;
            if (abs(current_average_diff) > DIFF_THRESHOLD)
                current_state = HIVE_STATE_HONEY;
            else
                current_state = HIVE_STATE_NOTHING_NEW;
            average_ticks_passed = 0;
            break;
        case HIVE_STATE_PROBLEM:
            sprintf(buffer, "There has been a problem : %0.1fkg of change in %d minutes !", current_measure_diff, MEASURE_INTERVAL / 60);
            current_state = HIVE_STATE_MSG;
            break;
        case HIVE_STATE_HONEY:
            sprintf(buffer, "There is more and more honey in the hive ! %0.1fkg of change in %d hours !", current_average_diff, AVERAGE_INTERVAL / 60);
            current_state = HIVE_STATE_MSG;
            break;
        case HIVE_STATE_NOTHING_NEW:
            sprintf(buffer, "Everything is fine ! %0.1fkg of change in %d hours !", current_average_diff, AVERAGE_INTERVAL / 60);
            current_state = HIVE_STATE_MSG;
            break;
        case HIVE_STATE_MSG:
            send_message(buffer);
            current_state = HIVE_STATE_INIT;
            break;
        default:
            pc.printf("Error...");
            break;
    }
}

void init_modem(void)
{
    MDMParser::DevStatus devStatus = {};
    MDMParser::NetStatus netStatus = {};
    
    // retry from begining if something fails
    while (!modem.init(SIMPIN, &devStatus, D4)) {
        pc.printf("\x1b[34m");
        pc.printf("MODEM init failed...\n\r");
        pc.printf("\x1b[0m");
        wait(1);
    }
    while (!modem.checkNetStatus(&netStatus)) {
        pc.printf("\x1b[34m");
        pc.printf("MODEM net_status failed...\n\r");
        pc.printf("\x1b[0m");
        wait(1);
    }
    modem.dumpDevStatus(&devStatus);
}

int main(void)
{
    // setting baud rate for serial communication with the pc
    pc.baud(115200);
    pc.printf("TEST\n\r");
    init_modem();

    // main loop
    while(1) {
        // blink once for each measure
        //blink();
        // getting sensor values
        // acquisition();
        // changing state of automata according to read values
        automate();
    }
}