Weather station project

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

main.cpp

Committer:
daniel_davvid
Date:
2018-07-01
Revision:
0:e42837021e1a

File content as of revision 0:e42837021e1a:

#include "mbed.h"

#ifndef M_PI
#define M_PI           3.1415926535897932384626433832795028841971693993751058209749445923078164
#endif
// DS1820 temp sens pin
#define MAX_PROBES      16
#define DATA_PIN        A0
//#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

//Analog pins
AnalogIn waterLevel(A1);
AnalogIn currentData(A2); 

// 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;

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

double desiredAngle, actualAngle;

//Functions
double angleDiff(double a, double b);   
int waterLevel();
int pirDetect();
float curentData();

int main()
{
    //Helios algorithm setup
    time_t seconds;
    char buffer[32];
    set_time(1529836800);  
    
    //Stepper enable
    stpCirc.enable();
    stpAngl.enable();
    //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();


    while (1) {
        
        //Helios
        seconds = time(NULL);
        sun.updatePosition();
        strftime(buffer, 32, "%H:%M:%S", localtime(&seconds));
        
        //SHT15
        busy = true;
        sensor.update();
        busy = false;
        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 (compassPollTimer.read() > 1) {
            compassPollTimer.reset();
            actualAngle = 360-compass.read();
            
            //Helios
            printf("UTC time is: %s\n", buffer);
            printf("Sun azimuth: %.2f, elevation: %.2f\n", sun.azimuth(), sun.elevation());
            
            //MAXI17043
            pc.printf("Vcell: %.2f\n", fuelGauge.getFloatVCell());
            pc.printf("Battery: %.2f\n", fuelGauge.getFloatSOC());
            
            //SHT15
            pc.printf("Temperature [ %3.2f C ]\r\n", sensor.getTemperature());
            pc.printf("Humdity     [ %3.2f %% ]\r\n\n", sensor.getHumidity());
            
            //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());   
            //
            
            lcd.setPageAddress(0,0);
            lcd.setColumnAddress(0,127);
            lcd.printf("Compass: %3.0f", actualAngle);
            pc.printf("Compass: %2.3f\n", actualAngle);
            //lcd.printf("Difference: %f\n", angleDiff(actualAngle, desiredAngle));
            
            lcd.setPageAddress(1,1);
            lcd.setColumnAddress(0,127);
            lcd.printf("Angle: %2.0f", acos(vertG)/M_PI*180.0f);
//            lcd.printf("Angle: %2.3f", vertG);
            pc.printf("Vertical angle: %1.3f\n", acos(vertG)/M_PI*180.0f);
            
            lcd.setPageAddress(2,2);
            lcd.setColumnAddress(0,127);
            lcd.printf("LUX: %4.0f", (bh.lux()/1.2f));
            pc.printf("Intensity: %5.2f lux\n", (bh.lux()/1.2f));
            
            pc.printf("Temp = %f\t Pres = %f\n", bmp.getTemperature(),bmp.getPressure());
            lcd.setPageAddress(3,3);
            lcd.setColumnAddress(0,127);
            lcd.printf("Temp: %.1f", bmp.getTemperature());
            lcd.setPageAddress(4,4);
            lcd.setColumnAddress(0,127);
            lcd.printf("Press: %4.f", bmp.getPressure());
           
            
            
            if (abs(angleDiff(actualAngle, desiredAngle)) > 5) {
                if (angleDiff(actualAngle, desiredAngle) > 0) {
                    stepper.setDirection(StepperController::DirectionCCW);
                    stpAngl.step(0, 1, 100);  
                }
                else {
                    stepper.setDirection(StepperController::DirectionCW);
                    stpAngl.step(0, 0, 100);    
                }   
                 
            }                 
        }
    }
}

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

int waterLevel(){
    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 currentData(){
    //VOUT=Vcc/2+i*VCC/36.7
    //i=36.7*Vout/Vcc-18.3
    
    float current;
    current = 36.7*(currentData.read()/3.3)-18.3;//???
    return current;
}