SysBee v1

Dependencies:   C027_Support mbed

Fork of App_Pese_Ruche_SYSBEE by Sysbee

main.cpp

Committer:
Cosi
Date:
2018-09-07
Revision:
6:b69c4870db2c
Parent:
5:d2702cbe5afe
Child:
7:95ddf8fa6260

File content as of revision 6:b69c4870db2c:

#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    (10 * 60)
// time between each averaging in s
#define AVERAGE_INTERVAL    (24 * 60 * 60)
//WEEK measure time interval
#define WEEK_INTERVALL (7 * 24 * 60 * 60)
// number of measure before average
#define AVERAGE_COUNT       ((int)(AVERAGE_INTERVAL / MEASURE_INTERVAL))

#define WEEK_COUNT        ((int)(WEEK_INTERVAL / AVERAGE_INTERVAL))

//#define SENSOR_OFFSET       6.1f
//#define SENSOR_FACTOR       39.0f
#define SENSOR_OFFSET       9.4f
#define SENSOR_FACTOR       26.3f

// 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_STANDBY,
    HIVE_STATE_WEEK,
    HIVE_STATE_AVERAGE,
    HIVE_STATE_MEASURE,
    HIVE_STATE_NOTHING_NEW,
    HIVE_STATE_HONEY,
    HIVE_STATE_PROBLEM_SPRING,
}               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 week_last_average = 0;
float current_average = 0;
float current_average_diff = 0;
float week_average_diff = 0;
float current_measure_diff = 0;
unsigned int average_ticks_passed = 0;
unsigned int week_ticks_passed = 0;
float 

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

// phone number for sms (Cosima DORLAND)
//const char phone_number[] = "0680182150";
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:
            // setting baud rate for serial communication with the pc
            pc.baud(115200);
            pc.printf("TEST\n\r");
            init_modem();
            current_state = HIVE_STATE_STANDBY;
        break;
            
        case HIVE_STATE_STANDBY:
            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)
            {
                sprintf(buffer, "3  There has been a problem : %0.1fkg of change in %d minutes !", current_measure_diff, MEASURE_INTERVAL / 60);
                send_message(buffer);
            }
            else
                current_state = HIVE_STATE_STANDBY;
            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 (current_average_diff > DIFF_THRESHOLD)
            {
                sprintf(buffer, "1  There is more and more honey in the hive ! %0.1fkg of change in %d hours !", current_average_diff, AVERAGE_INTERVAL / 60);
                send_message(buffer);
            }
            else if (current_average_diff < -DIFF_THRESHOLD)
            {
                sprintf(buffer, "2  There is less honey ! %0.1fkg of change in %d hours !", current_average_diff, AVERAGE_INTERVAL / 60);
                send_message(buffer);
            }
            else
            {
                sprintf(buffer, "0  Everything is fine ! %0.1fkg of change in %d hours !", current_average_diff, AVERAGE_INTERVAL / 60);
                send_message(buffer);
            }
            average_ticks_passed = 0;
            current_state = HIVE_STATE_STANDBY;
            break;
        
        case HIVE_STATE_WEEK:
            week_average = 0;
            for(int i = 0; i < week_ticks_passed; i++) {
                week_average += average_values[i];
                
            }
            week_average /= week_ticks_passed;
            week_average_diff = week_average - week_last_average;
            week_last_average = week_average;
            if (week_average_diff > DIFF_THRESHOLD)
            {
                sprintf(buffer, "4  There is more and more honey in the hive over the week! %0.1fkg of change in %d hours !", week_average_diff, WEEK_INTERVAL / 60);
                send_message(buffer);
            }
            else if (week_average_diff < -DIFF_THRESHOLD)
            {
                sprintf(buffer, "5  There is less honey over the week ! %0.1fkg of change in %d hours !", week_average_diff, WEEK_INTERVAL / 60);
                send_message(buffer);
            }
            else
            {
                sprintf(buffer, "6  Everything was fine over the last week  ! %0.1fkg of change in %d hours !", week_average_diff, WEEK_INTERVAL / 60);
                send_message(buffer);
            }
            week_ticks_passed = 0;
            current_state = HIVE_STATE_STANDBY;
            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)
{
  
   

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