![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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_project by
Revision 3:44517d2520e1, committed 2018-07-04
- Comitter:
- daniel_davvid
- Date:
- Wed Jul 04 19:37:10 2018 +0000
- Parent:
- 2:bc1c1f395e9a
- Commit message:
- Update v1.2
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r bc1c1f395e9a -r 44517d2520e1 main.cpp --- a/main.cpp Wed Jul 04 06:41:14 2018 +0000 +++ b/main.cpp Wed Jul 04 19:37:10 2018 +0000 @@ -1,11 +1,17 @@ #include "mbed.h" -#define DONT_MOVE 1 +#define DONT_MOVE 0 #define UPDATE_RTC_TIME 0 #define RTC_TIME 1530462446 +#define DISPLAY_INTERVAL 0.5f +#define SUN_POS_INTERVAL 10// one minute for sun position update using + // the Helios algorithm +#define PLATFORM_POSITION_POLL_INTERVAL 1 // read platform position sensors +#define WEATHER_STATE_UPDATE_INTERVAL 1 + #ifndef M_PI -#define M_PI 3.1415926535897932384626433832795028841971693993751058209749445923078164 +#define M_PI 3.1415926535897932384626433832795028841971693993751058209749445923078164f #endif // DS1820 temp sens pin #define MAX_PROBES 16 @@ -24,9 +30,10 @@ #include "stepper.h" //Stepping motor lib. Serial pc(USBTX, USBRX); +//Serial pi(D1, D0); //Digital pins -DigitalIn maxAnglLimit(PC_8); -DigitalIn minAnglLimit(PC_6); +DigitalIn maxAngleLimit(PC_8); +DigitalIn minAngleLimit(PC_6); DigitalOut swPi(PC_5); DigitalIn pir(PB_12); //Analog pins @@ -35,7 +42,7 @@ // 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); +stepper stpAngle(PA_11, NC, NC, NC, PB_14, PB_15); //DS1820 setup DS1820* probe[MAX_PROBES]; @@ -49,7 +56,7 @@ //I2C i2c3(D5, D7); // Maybe change the format -SHTx::SHT15 sensor(D5, D7); +SHTx::SHT15 sht(D5, D7); //I2C 1 sensors BH1750 bh(i2c1); @@ -63,38 +70,262 @@ MPU6050 mpu(i2c2); // Timers +Timer sunPosUpdateTimer; +Timer platformPositionPollTimer; +Timer platformRotateTimer; +Timer panelTiltTimer; +Timer pirPollTimer; +Timer weatherStateUpdateTimer; Timer displayTimer; -Timer stepperRelaxTimer; -Timer compassPollTimer; -Timer pirPollTimer; + -//Accel -//not needed? -Vector rawGyro, normGyro; -Vector rawAccel, normAccel; -// +// platform rotate & panel tilt +// timer intervals +float platformRotateInterval; +float panelTiltInterval; + +// Accelerometer readings Vector scaledAccel; -float vertG; -//Compass +float vertG; // Z axis component of the g +float accelDesiredAngle, accelActualAngle; -double desiredAngle, actualAngle; -int crtFrame = 0; +//Compass +float compassDesiredAngle, compassActualAngle; + + +// PIR state variable and update interval bool pirDetectionOccured = false; +// 60 seconds warm-up for first update int pirUpdateInterval = 60; -//Functions -double angleDiff(double a, double b); -int getWaterLevel(); -void updatePirState(); -float getCrtConsumption(); +// LCD displays current shown page +int crtPage = 0; + +// Auxiliary variables for RTC time +// readings +time_t seconds; +char buffer[32]; + + +//Function forward declarations +void init(); // setup all devices + +float compassAngleDiff(float a, float b); // compute angle difference between + // the compass read angle and the + // desired angle + +float accelAngleDiff(float a, float b); + +int getWaterLevel(); // read the water level sensor + +void updatePirState(); // read the PIR state and update + // state variable + +float getCrtConsumption(); // read the current sensor int main() { - maxAnglLimit.mode(PullUp); - minAnglLimit.mode(PullUp); - //Helios algorithm setup - time_t seconds; - char buffer[32]; + //Sensor variable names + float lightIntensity; + float bmpTemp, pressure; + float humidity, shtTemp; + float crtConsumption; + float VCell, SOC; + float temperature; + int maxAngle, minAngle; + // initialize all devices + init(); + + while (1) { + + //Helios + if (sunPosUpdateTimer.read() > SUN_POS_INTERVAL) { + seconds = time(NULL); + strftime(buffer, 32, "%H:%M:%S", localtime(&seconds)); + sun.updatePosition(); + compassDesiredAngle = sun.azimuth(); + accelDesiredAngle = sun.elevation(); + } + + if (pirPollTimer.read() > pirUpdateInterval) { + pirPollTimer.reset(); + pirUpdateInterval = 1; + updatePirState(); + } + + if (platformPositionPollTimer.read() > PLATFORM_POSITION_POLL_INTERVAL) { + platformPositionPollTimer.reset(); + // read compass + compassActualAngle = 360-compass.read(); + + // read accelerometer + 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; + accelActualAngle = acos(vertG)/M_PI*180.0f; + } + + if (weatherStateUpdateTimer.read() > WEATHER_STATE_UPDATE_INTERVAL) { + weatherStateUpdateTimer.reset(); + //DS1820 sensor + probe[0]->convertTemperature(true, DS1820::all_devices); + for (int i = 0; i<1; i++) + pc.printf("Device %d returns %3.1foC\r\n", i, probe[i]->temperature()); + //SHT15 + sht.update(); + sht.setScale(false); + + //Sensor data to variables + lightIntensity = bh.lux()/1.2f; + bmpTemp = bmp.getTemperature(); + pressure = bmp.getPressure(); + shtTemp = sht.getTemperature(); + humidity = sht.getHumidity(); + crtConsumption = getCrtConsumption()*1000; + probe[0]->convertTemperature(true, DS1820::all_devices); + temperature = probe[0]->temperature(); + VCell = fuelGauge.getFloatVCell(); + SOC = fuelGauge.getFloatSOC(); + maxAngle = maxAngleLimit.read(); + minAngle = minAngleLimit.read(); + azimuth = sun.azimuth(); + elevation = sun.elevation(); + } + + if (platformRotateTimer.read() > platformRotateInterval) { + platformRotateTimer.reset(); + // rotate the platform to reach the desired compass + // indication + float angleDiff = compassAngleDiff(compassActualAngle, compassDesiredAngle); + if (abs(angleDiff) > 5) { + if (!DONT_MOVE) { + if (angleDiff > 0) { + stpCirc.step(0, 1, 30000); + } + else { + stpCirc.step(0, 0, 30000); + } + } + } + + // change the rotate interval according to angle difference + // for large differences, make the update interval shorter + if (abs(angleDiff) > 10) { + platformRotateInterval = 0.1f; + } + else { + platformRotateInterval = 1.0f; + } + } + + if (panelTiltTimer.read() > panelTiltInterval) { + panelTiltTimer.reset(); + // tilt the panel to reach the desired accelerometer + // indication + + float angleDiff = accelAngleDiff(accelActualAngle, accelDesiredAngle); + if (abs(angleDiff) > 2) { + if (!DONT_MOVE) { + if (angleDiff > 0 && !maxAngleLimit.read()) { + stpAngle.step(0, 1, 30000); + } + else if (!minAngleLimit.read()) { + stpAngle.step(0, 0, 30000); + } + } + } + // change the rotate interval according to angle difference + // for large differences, make the update interval shorter + if (abs(angleDiff) > 5) { + panelTiltInterval = 0.1f; + } + else { + panelTiltInterval = 1.0f; + } + } + if (displayTimer.read() > DISPLAY_INTERVAL) { + 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", VCell); + pc.printf("Battery: %.2f\n", SOC); + pc.printf("Temperature [ %3.2f C ]\r\n", shtTemp); + pc.printf("Humdity [ %3.2f %% ]\r\n\n", humidity); + pc.printf("Compass: %2.3f\n", compassActualAngle); + pc.printf("Vertical angle: %1.3f\n", accelActualAngle); + pc.printf("Intensity: %5.2f lux\n", lightIntensity); + pc.printf("Temp = %f\t Pres = %f\n", bmpTemp,pressure); + if (crtPage == 0) { + lcd1.setPageAddress(0,0); + lcd1.setColumnAddress(0,127); + lcd1.printf("Compass: %3.0f", compassActualAngle); + //lcd.printf("Difference: %f\n", compassAngleDiff(compassActualAngle, compassDesiredAngle)); + + lcd1.setPageAddress(1,1); + lcd1.setColumnAddress(0,127); + lcd1.printf("Angle: %2.0f", accelActualAngle); + lcd1.setPageAddress(2,2); + lcd1.setColumnAddress(0,127); + lcd1.printf("LUX: %4.0f", lightIntensity); + lcd1.setPageAddress(3,3); + lcd1.setColumnAddress(0,127); + lcd1.printf("Temp: %.1f", bmpTemp); + lcd1.setPageAddress(4,4); + lcd1.setColumnAddress(0,127); + lcd1.printf("Press: %4.f", pressure); + lcd1.setPageAddress(5,5); + lcd1.setColumnAddress(0,127); + lcd1.printf("Max: %d", maxAngle); + lcd1.setPageAddress(6,6); + lcd1.setColumnAddress(0,127); + lcd1.printf("Min: %d", minAngle); + 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", azimuth); + lcd2.setPageAddress(1,1); + lcd2.setColumnAddress(0,127); + lcd2.printf("ELV: %.2f", elevation); + + //MAXI17043 + lcd2.setPageAddress(2,2); + lcd2.setColumnAddress(0,127); + lcd2.printf("Vcell: %.2f\n", VCell); + lcd2.setPageAddress(3,3); + lcd2.setColumnAddress(0,127); + lcd2.printf("Battery: %.2f\n",SOC); + + //SHT15 + lcd2.setPageAddress(4,4); + lcd2.setColumnAddress(0,127); + lcd2.printf("Temp: %3.2f C", shtTemp); + lcd2.setPageAddress(5,5); + lcd2.setColumnAddress(0,127); + lcd2.printf("Hum: %3.2f%%", humidity); + lcd2.setPageAddress(6,6); + lcd2.setColumnAddress(0,127); + lcd2.printf("Crt: %03.1fmA", crtConsumption); + lcd2.setPageAddress(7,7); + lcd2.setColumnAddress(0,127); + lcd2.printf("Temp %2.1f C",temperature); + + } + else { + } + crtPage = (crtPage + 1) & 1; + } + } +} + +void init() +{ + maxAngleLimit.mode(PullUp); + minAngleLimit.mode(PullUp); if (UPDATE_RTC_TIME) { set_time(RTC_TIME); @@ -102,17 +333,17 @@ // Stepper drivers setup if (DONT_MOVE) { - stpAngl.disable(); + stpAngle.disable(); stpCirc.disable(); } else { - stpAngl.enable(); + stpAngle.enable(); stpCirc.enable(); } swPi = 0; //SHT15 setup - sensor.setOTPReload(false); - sensor.setResolution(true); + sht.setOTPReload(false); + sht.setResolution(true); // DS1820 setup int num_devices = 0; @@ -136,154 +367,31 @@ bh.init(); // compass.init(); - desiredAngle = 0.0; //** SET BY HELIOS LIB!!!!** - - //Timers Start + compassDesiredAngle = 0.0f; + accelDesiredAngle = 45.0f; + + platformRotateInterval = 0.1f; + panelTiltInterval = 0.1f; + + //Timers Start + platformRotateTimer.start(); + panelTiltTimer.start(); + weatherStateUpdateTimer.start(); displayTimer.start(); - compassPollTimer.start(); + platformPositionPollTimer.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; - } - } + sunPosUpdateTimer.start(); } -double angleDiff(double a, double b) +float accelAngleDiff(float a, float b) { - double diff = a - b; + float diff = a - b; + return diff; +} + +float compassAngleDiff(float a, float b) +{ + float diff = a - b; if (diff > 180) diff -= 360; @@ -292,6 +400,7 @@ return diff; } + int getWaterLevel(){ float value; value = waterLevel.read() *1000;