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