Weather station project updated display and sensors

Dependencies:   BH1750 BMP280 DS1820 HMC5983 Helios MAX17043 MPU6050 SHTx SSD1306_I2C A4988_stepper mbed

Fork of weather_station_proj by Daniel David

main.cpp

Committer:
daniel_davvid
Date:
2018-07-04
Revision:
2:bc1c1f395e9a
Parent:
1:f20e1ea0302e

File content as of revision 2:bc1c1f395e9a:

#include "mbed.h"

#define DONT_MOVE 1
#define UPDATE_RTC_TIME 0
#define RTC_TIME 1530462446

#ifndef M_PI
#define M_PI           3.1415926535897932384626433832795028841971693993751058209749445923078164
#endif
// DS1820 temp sens pin
#define MAX_PROBES      16
#define DATA_PIN        A1
//#define MULTIPLE_PROBES

#include "BH1750.h"         //Light sensor lib
#include "BMP280.h"         //Pressure sensor lib
#include "DS1820.h"         //Temp sensor lib (One wire)
#include "Helios.h"         //Sun tracking algorithm
#include "HMC5983.h"        //Compass lib
#include "MAX17043.h"       //Fuel gauge sens lib
#include "MPU6050.h"        //Accelerometer sensor lib
#include "SHTx/sht15.hpp"     //Humidity sens lib
#include "SSD1306.h"        //Display lib
#include "stepper.h"        //Stepping motor lib.

Serial pc(USBTX, USBRX);
//Digital pins
DigitalIn maxAnglLimit(PC_8);
DigitalIn minAnglLimit(PC_6);
DigitalOut swPi(PC_5);
DigitalIn pir(PB_12);
//Analog pins
AnalogIn waterLevel(A2);
AnalogIn crtConsumption(A3); 

// Stepper motor setup
stepper stpCirc(PA_12, NC, NC, NC, PB_1, PB_2);
stepper stpAngl(PA_11, NC, NC, NC, PB_14, PB_15);

//DS1820 setup
DS1820* probe[MAX_PROBES];

//Helios algorithm
Helios sun;

// I2C communication setup
I2C i2c1(D14, D15);
I2C i2c2(D3, D6);
//I2C i2c3(D5, D7);

// Maybe change the format
SHTx::SHT15 sensor(D5, D7);

//I2C 1 sensors
BH1750 bh(i2c1);
BMP280 bmp(i2c1);
HMC5983 compass(i2c1);
MAX17043 fuelGauge(i2c1);
SSD1306 lcd1(&i2c1, 0x78);

//I2C 2 sensors
SSD1306 lcd2(&i2c2, 0x78);
MPU6050 mpu(i2c2);

// Timers 
Timer displayTimer;
Timer stepperRelaxTimer;
Timer compassPollTimer;
Timer pirPollTimer;

//Accel
//not needed?
Vector rawGyro, normGyro;
Vector rawAccel, normAccel;
//
Vector scaledAccel; 
float vertG;
//Compass

double desiredAngle, actualAngle;
int crtFrame = 0;
bool pirDetectionOccured = false;
int pirUpdateInterval = 60;

//Functions
double angleDiff(double a, double b);   
int getWaterLevel();
void updatePirState();
float getCrtConsumption();

int main()
{
    maxAnglLimit.mode(PullUp);
    minAnglLimit.mode(PullUp);
    //Helios algorithm setup
    time_t seconds;
    char buffer[32];

    if (UPDATE_RTC_TIME) {
        set_time(RTC_TIME);
    }

    // Stepper drivers setup
    if (DONT_MOVE) {
        stpAngl.disable();
        stpCirc.disable();
    }
    else {
        stpAngl.enable();
        stpCirc.enable();
    }
    swPi = 0;
    //SHT15 setup
    sensor.setOTPReload(false);
    sensor.setResolution(true);

    // DS1820 setup
    int num_devices = 0;
    while(DS1820::unassignedProbe(DATA_PIN)) {
        probe[num_devices] = new DS1820(DATA_PIN);
        num_devices++;
        if (num_devices == MAX_PROBES)
            break;
    }
    //MPU setup
    while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) {
        pc.printf("Could not find a valid MPU6050 sensor, check wiring!\n");
        wait(0.5);
    }
    mpu.calibrateGyro();
    mpu.setThreshold(3);
    
    //BMP setup
    bmp.initialize();
    //BH setup
    bh.init();
    //
    compass.init();
    desiredAngle = 0.0;     //** SET BY HELIOS LIB!!!!**
   
   //Timers Start
    displayTimer.start();
    compassPollTimer.start();
    pirPollTimer.start();


    while (1) {
        
        //Helios
        seconds = time(NULL);
        sun.updatePosition();
        strftime(buffer, 32, "%H:%M:%S", localtime(&seconds));
        
        //SHT15
        sensor.update();
        sensor.setScale(false);
        
        //MPU readings
        // not needed?
        rawGyro = mpu.readRawGyro();
        normGyro = mpu.readNormalizeGyro();
        rawAccel = mpu.readRawAccel();
        normAccel = mpu.readNormalizeAccel();
        // (ADD TO A new READ FUNCTION in lib???)
        scaledAccel = mpu.readScaledAccel();
        vertG = scaledAccel.ZAxis;
        vertG = vertG > 2.0f ? 3.9f - vertG : vertG;
        vertG = vertG < 1.0f ? vertG : 1.0f;
        vertG = vertG > -1.0f ? vertG : -1.0f;
               
        if (pirPollTimer.read() > pirUpdateInterval) {
            pirPollTimer.reset();
            pirUpdateInterval = 1;
            updatePirState();
        }
        
        if (compassPollTimer.read() > 1) {
            compassPollTimer.reset();
            actualAngle = 360-compass.read();
            
            //Helios
            
            //DS1820 sensor
            probe[0]->convertTemperature(true, DS1820::all_devices);  
            for (int i = 0; i<num_devices; i++)
                pc.printf("Device %d returns %3.1foC\r\n", i, probe[i]->temperature());   
            //
            
           
            
            
            if (abs(angleDiff(actualAngle, desiredAngle)) > 5) {
                if (angleDiff(actualAngle, desiredAngle) > 0 && !DONT_MOVE) {
                    stpAngl.step(0, 1, 100);  
                }
            }
            else {
                if (!DONT_MOVE) {
                    stpAngl.step(0, 0, 100);    
                }
            }   
                 
        }
        if (displayTimer.read() > 0.5) {
            displayTimer.reset();
            pc.printf("UTC time is: %s\n", buffer);
            pc.printf("Sun azimuth: %.2f, elevation: %.2f\n", sun.azimuth(), sun.elevation());
            pc.printf("Vcell: %.2f\n", fuelGauge.getFloatVCell());
            pc.printf("Battery: %.2f\n", fuelGauge.getFloatSOC());
            pc.printf("Temperature [ %3.2f C ]\r\n", sensor.getTemperature());
            pc.printf("Humdity     [ %3.2f %% ]\r\n\n", sensor.getHumidity());
            pc.printf("Compass: %2.3f\n", actualAngle);
            pc.printf("Vertical angle: %1.3f\n", acos(vertG)/M_PI*180.0f);
            pc.printf("Intensity: %5.2f lux\n", (bh.lux()/1.2f));            
            pc.printf("Temp = %f\t Pres = %f\n", bmp.getTemperature(),bmp.getPressure());
            if (crtFrame == 0) {
                lcd1.setPageAddress(0,0);
                lcd1.setColumnAddress(0,127);
                lcd1.printf("Compass: %3.0f", actualAngle);
                //lcd.printf("Difference: %f\n", angleDiff(actualAngle, desiredAngle));
                
                lcd1.setPageAddress(1,1);
                lcd1.setColumnAddress(0,127);
                lcd1.printf("Angle: %2.0f", acos(vertG)/M_PI*180.0f);
    //            lcd.printf("Angle: %2.3f", vertG);
                
                lcd1.setPageAddress(2,2);
                lcd1.setColumnAddress(0,127);
                lcd1.printf("LUX: %4.0f", (bh.lux()/1.2f));
                lcd1.setPageAddress(3,3);
                lcd1.setColumnAddress(0,127);
                lcd1.printf("Temp: %.1f", bmp.getTemperature());
                lcd1.setPageAddress(4,4);
                lcd1.setColumnAddress(0,127);
                lcd1.printf("Press: %4.f", bmp.getPressure());
                lcd1.setPageAddress(5,5);
                lcd1.setColumnAddress(0,127);
                lcd1.printf("Max: %d", maxAnglLimit.read());
                lcd1.setPageAddress(6,6);
                lcd1.setColumnAddress(0,127);
                lcd1.printf("Min: %d", minAnglLimit.read());
                lcd1.setPageAddress(7,7);
                lcd1.setColumnAddress(0,127);
                lcd1.printf("PIR: %s", pirDetectionOccured ? "DETECTED" : "NOTHING ");

                lcd2.setPageAddress(0,0);
                lcd2.setColumnAddress(0,127);
                lcd2.printf("AZMT: %.2f", sun.azimuth());
                lcd2.setPageAddress(1,1);
                lcd2.setColumnAddress(0,127);
                lcd2.printf("ELV: %.2f",sun.elevation());
                
                //MAXI17043
                lcd2.setPageAddress(2,2);
                lcd2.setColumnAddress(0,127);
                lcd2.printf("Vcell: %.2f\n", fuelGauge.getFloatVCell());
                lcd2.setPageAddress(3,3);
                lcd2.setColumnAddress(0,127);
                lcd2.printf("Battery: %.2f\n", fuelGauge.getFloatSOC());
                
                //SHT15
                lcd2.setPageAddress(4,4);
                lcd2.setColumnAddress(0,127);
                lcd2.printf("Temp: %3.2f C", sensor.getTemperature());
                lcd2.setPageAddress(5,5);
                lcd2.setColumnAddress(0,127);
                lcd2.printf("Hum: %3.2f%%", sensor.getHumidity());
                lcd2.setPageAddress(6,6);
                lcd2.setColumnAddress(0,127);
                lcd2.printf("Crt: %03.1fmA", getCrtConsumption()*1000);
                lcd2.setPageAddress(7,7);
                lcd2.setColumnAddress(0,127);
                probe[0]->convertTemperature(true, DS1820::all_devices);  
                lcd2.printf("Temp %2.1f C",probe[0]->temperature());  

            }
            else {
            }
            crtFrame = (crtFrame + 1) & 1;
        }
    }
}

double angleDiff(double a, double b)
{
    double diff = a - b;
    
    if (diff > 180)
        diff -= 360;
    if (diff < -180)
        diff += 360;
    return diff;
}

int getWaterLevel(){
    float value;
    value = waterLevel.read() *1000;
        if (value<=150) {
            value=0;
        } else if (value>150 && value<=210) {
            value=1/4;
        } else if (value>210 && value<=250) {
            value=1/2;
        } else if (value>250 && value<=350) {
            value=3/4;;
        } else if (value>350) {
            value=1;
        }
    value=value*100; //final data in x%
    return value;
}

float getCrtConsumption(){
    //VOUT=Vcc/2+i*VCC/36.7
    //i=36.7*Vout/Vcc-18.3
    
    float result = 36.7f * crtConsumption.read() - 18.3f;
    result = result < 0 ? 0.0f : result;
    
    return result;
}

void updatePirState() {
    pirDetectionOccured = pir.read() != 0;
}