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 Daniel David

Revision:
3:44517d2520e1
Parent:
2:bc1c1f395e9a
--- 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;