Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 |
--- 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;
