iot_water_monitor_v2

Dependencies:   easy-connect-v16 Watchdog FP MQTTPacket RecordType-v-16 watersenor_and_temp_code

Sensor/ReadSensor.cpp

Committer:
DuyLionTran
Date:
2018-04-03
Revision:
57:898fcb6692cd
Parent:
55:c405323f8d5a

File content as of revision 57:898fcb6692cd:

#include "mbed.h"
#include "DS1820.h"
#include "ReadSensor.h"
#include "flash_programming.h"

const float SaturationValueTab[41] = {      /* saturation dissolved oxygen concentrations at various temperatures */
14.46, 14.22, 13.82, 13.44, 13.09,          /* 0 degree Celcius */
12.74, 12.42, 12.11, 11.81, 11.53,
11.26, 11.01, 10.77, 10.53, 10.30,
10.08, 9.86,  9.66,  9.46,  9.27,
9.08,  8.90,  8.73,  8.57,  8.41,
8.25,  8.11,  7.96,  7.82,  7.69,
7.56,  7.43,  7.30,  7.18,  7.07,
6.95,  6.84,  6.73,  6.63,  6.53,
6.41,                                       /* 40 degree Celcius */  
};

enum {
    CALIBRATION = 1,
    SATCAL,
    EXIT
} Calibration_Mode;

float   doValue;                                /* current dissolved oxygen value, unit; mg/L or ppm */
#ifdef PROBE_EXIST
    float   temperature;                        
#else
    float   temperature = 25.0;                 /* default temperature is 25^C, you can use a temperature sensor to read it */
#endif
int     analogBuffer[SCOUNT];                   /* store the analog value in the array, readed from ADC */
int     analogBufferTemp[SCOUNT];
int     analogBufferIndex       = 0;
int     copyIndex               = 0;
float   SaturationDoVoltage;                    /* mV */
float   SaturationDoTemperature;                /* ^C */
float   averageVoltage;
bool    isCalibrating           = false;

AnalogIn     DOSensor(SENSOR_2_PIN);

/* Error often occurs here */
DS1820       probe(SENSOR_1_PIN);

int getMedianNum(int bArray[], int iFilterLen) {
    int bTab[iFilterLen];
    for (uint8_t i = 0; i < iFilterLen; i++) {
        bTab[i] = bArray[i];
    }
    int i, j;
    int bTemp;
    for (j = 0; j < iFilterLen - 1; j++) {
        for (i = 0; i < iFilterLen - j - 1; i++) {
            if (bTab[i] > bTab[i + 1]) {
                bTemp = bTab[i];
                bTab[i] = bTab[i + 1];
                bTab[i + 1] = bTemp;
            }
        }
    }
    if ((iFilterLen & 1) > 0) {
        bTemp = bTab[(iFilterLen - 1) / 2];
    }
    else {
        bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
    }
    return bTemp;
}

void SENSOR_AnalogRead() {
    /* Convert from 0 - 1 (float) resolution to 10-bit ADC resolution */
    /* Same as the example from DFRobot Arduino */
    float analogReadRaw = DOSensor.read();
    float voltageRaw    = analogReadRaw*3.3;
    analogBuffer[analogBufferIndex] = (int)((voltageRaw * 1023.0)/5.0);
    
//    printf("Analog read %d %d\r\n", analogBufferIndex, analogBuffer[analogBufferIndex]);
    analogBufferIndex++;
    if(analogBufferIndex == SCOUNT) {
        analogBufferIndex = 0;
    }
}

void SENSOR_GetDOValue() {
    /* Read temperature */
    #ifdef PROBE_EXIST
        wait(0.2);
        probe.startConversion();  
        temperature = probe.read();     
    #endif
    
    for(copyIndex = 0; copyIndex < SCOUNT; copyIndex++) {
        analogBufferTemp[copyIndex]= analogBuffer[copyIndex];
    }   
    /* read the value more stable by the median filtering algorithm */
    averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF/1024.0; 
    printf("Average voltage %.2f\r\n", averageVoltage);
    /* calculate the do value, doValue = Voltage / SaturationDoVoltage * SaturationDoValue(with temperature compensation) */
    SaturationDoTemperature = temperature;
    doValue =  (SaturationValueTab[(int)(SaturationDoTemperature + 0.5)] * averageVoltage) / (float)(SaturationDoVoltage);  
    float a = 1;
    printf("SaturationDoTemperature %.2f; SaturationDoVoltage %.2f; DO Value %.2f mg/L\r\n", SaturationDoTemperature, SaturationDoVoltage, doValue/a);
}

void SENSOR_DoCalibration(uint8_t CurrentCalibrationMode) {
    static bool doCalibrationFinishFlag = false, enterCalibrationFlag = false;
    float voltageValueStore;
    
    switch (CurrentCalibrationMode) {
        case 0: 
            if(enterCalibrationFlag) {
                printf("Command Error\r\n");
            }
        break;
        
        case CALIBRATION:
            enterCalibrationFlag    = true;
            doCalibrationFinishFlag = false;
            printf(">>>Enter Calibration Mode<<<\r\n");
            printf(">>>Please put the probe into the saturation oxygen water!<<<\r\n\r\n");   
        break;
        
        case SATCAL:
            if (enterCalibrationFlag) {
                printf("\r\n>>>Saturation Calibration Finish!<<<\r\n\r\n");
                /* Convert from float to uint32_t */
                uint32_t tempAverageVoltage = (uint32_t)averageVoltage;
                if ((averageVoltage - 0.5) >= (float)(tempAverageVoltage)) {
                    tempAverageVoltage++;
                }
                printf("averageVoltage %d\r\n", (uint32_t)tempAverageVoltage);  
                
                FP_WriteConfigValues((uint32_t)(tempAverageVoltage));
                SaturationDoVoltage = averageVoltage;
                doCalibrationFinishFlag = true;
            }         
        break;
        
        case EXIT:
            if (enterCalibrationFlag) {
                if(doCalibrationFinishFlag)  {
                   printf("\r\n>>>Calibration Successful\r\n");
                }          
                else  {
                  printf(">>>Calibration Failed\r\n");
                }
                printf("Exit Calibration Mode<<<\r\n\r\n");
                doCalibrationFinishFlag = false;
                enterCalibrationFlag    = false;
                NVIC_SystemReset(); 
            }        
        break;
        
        default: break;
    }
}

void SENSOR_ReadDoCharacteristicValues() {
    if (probe.begin()) {
        printf("sensor found\r\n");
        probe.startConversion();    
        wait(0.5);        
    }
    uint32_t int_SaturationDoVoltage = FP_ReadValue(SAT_DO_VOLT_ADDRESS);
    printf("Read SaturationDoVoltage %d\r\n", int_SaturationDoVoltage);
    SaturationDoVoltage = (float)int_SaturationDoVoltage;
    printf("SaturationDoVoltage %f\r\n", SaturationDoVoltage);
    if (FP_ReadValue(SAT_DO_VOLT_ADDRESS) == 0xFF) {
        /* default voltage: 1127V */
        SaturationDoVoltage = 1127.6;     
        int_SaturationDoVoltage = (uint32_t)SaturationDoVoltage;
        if ((SaturationDoVoltage - 0.5) >= (float)(int_SaturationDoVoltage)) {
            int_SaturationDoVoltage++;
        }
        printf("SaturationDoVoltage %d\r\n", (uint32_t)int_SaturationDoVoltage);  
        FP_WriteConfigValues((uint32_t)(int_SaturationDoVoltage));
    }
}