Weather station project

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

Files at this revision

API Documentation at this revision

Comitter:
daniel_davvid
Date:
Sun Jul 01 12:11:00 2018 +0000
Commit message:
Weather station project based on multiple sensors

Changed in this revision

BH1750.lib Show annotated file Show diff for this revision Revisions of this file
BMP280.lib Show annotated file Show diff for this revision Revisions of this file
DS1820.lib Show annotated file Show diff for this revision Revisions of this file
HMC5983.lib Show annotated file Show diff for this revision Revisions of this file
Helios.lib Show annotated file Show diff for this revision Revisions of this file
MAX17043.lib Show annotated file Show diff for this revision Revisions of this file
MPU6050.lib Show annotated file Show diff for this revision Revisions of this file
SHTx.lib Show annotated file Show diff for this revision Revisions of this file
SSD1306_128x64_I2C.lib Show annotated file Show diff for this revision Revisions of this file
STEPPER.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
rtc_prog.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BH1750.lib	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/daniel_davvid/code/BH1750/#2d9ef50ea9d3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BMP280.lib	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/daniel_davvid/code/BMP280/#3a0af995dd4c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DS1820.lib	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/Sissors/code/DS1820/#236eb8f8e73a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HMC5983.lib	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/acracan/code/HMC5983/#cffff4c45a14
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Helios.lib	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/acracan/code/Helios/#ad31da30ae64
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX17043.lib	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/daniel_davvid/code/MAX17043/#4287b7d9c9ca
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MPU6050.lib	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/daniel_davvid/code/MPU6050/#aef0335c060b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SHTx.lib	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/NegativeBlack/code/SHTx/#8465801be23f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SSD1306_128x64_I2C.lib	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/daniel_davvid/code/SSD1306_I2C/#05989d252f62
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/STEPPER.lib	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/daniel_davvid/code/A4988_stepper/#3ea32ec0e172
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,249 @@
+#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;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/a7c7b631e539
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtc_prog.cpp	Sun Jul 01 12:11:00 2018 +0000
@@ -0,0 +1,278 @@
+/*
+ * mbed Application program
+ *      RTC (inside STM32x CPU) test program
+ *
+ * Copyright (c) 2015,'16,'17 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Created: January   17th, 2015
+ *      Revised: January   16th, 2017
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*  mbed library now suports RTC continuous operation at Reset & Power ON/OFF
+    --------------------------------------------------------------------------
+    In the past, rtc_api.c (inside mbed) alway made a reset RTC registers
+    when user push a reset buttom or terninate a power.
+    Even if user configures a back-up circuit for RTC, mbed board could not
+    keep proper time.
+    I have checked mbed rev.133 and mbed-dev rev.155.
+ */
+
+/*
+    ----- Tested board -----
+                  / Reset: / Stanby: / power off and restart:
+    Nucleo-F401RE /  ok    /  ok     / ok (need following Back-up Circuit)
+    Nucleo-F411RE /  ok    /  ok     / ok (need following Back-up Circuit)
+    Nucleo-F446RE /  ok    /  ok     / ok (need following Back-up Circuit)
+    Nucleo-F334R8 /  ok    /  ok     / ok (need following Back-up Circuit)
+    Nucleo-L476RG /  ok    /  ok     / ok (need following Back-up Circuit)
+    Nucleo-L152RE /  ok    /  ok     / no check (Need additional hardware)
+    Nucleo-L073RZ /  ok    /  ok     / no check (Need additional hardware)
+    Nucleo-L053R8 /  ok    /  ok     / no check (Need additional hardware)
+
+    < Back-up circuit >
+    CN7 VIN <- SBD <- 330 Ohm <- CR2032 + - -> CN7 GND
+    Remove SB45 Zero Ohm resistor
+ */
+ 
+ -------------------------/*
+
+//  Include --------------------------------------------------------------------
+#include "mbed.h"
+
+//  Definition -----------------------------------------------------------------
+#if (defined(TARGET_STM32F746NG) || defined(TARGET_STM32F746ZG))
+#define PUSHED_SW   1   // Active high
+#else
+#define PUSHED_SW   0   // Active low
+#endif
+
+//  Object ---------------------------------------------------------------------
+DigitalIn userSW(USER_BUTTON);
+DigitalOut myled(LED1);         // Indicate the sampling period
+Serial pc(USBTX, USBRX);
+
+//  RAM ------------------------------------------------------------------------
+
+//  ROM / Constant data --------------------------------------------------------
+char *const msg0 = "Is a time correct? If no, please hit any key. ";
+char *const msg1 = "<Push USER SW then enter sleep mode> ";
+char *const msg2 = "\r\nEnter Standby Mode, please push RESET to wake-up\r\n";
+
+//  Function prototypes --------------------------------------------------------
+static void time_enter_mode(void);
+static void chk_and_set_time(char *ptr);
+static void goto_standby(void);
+static int xatoi (char **str, unsigned long *res);
+static void get_line (char *buff, int len);
+
+//------------------------------------------------------------------------------
+//  Control Program
+//------------------------------------------------------------------------------
+int main()
+{
+    char buf[64];               // data buffer for text
+    time_t seconds;
+    uint8_t wait_counter = 0;
+
+    wait(2.0);
+    pc.printf("\r\n\r\nTest Nucleo RTC Function\r\n");
+    myled = !myled;
+    // waiting for Initial screen
+    myled = 1;
+    wait(1.0);
+    myled = !myled;
+    wait(1.0);
+    while(1) {
+        seconds = time(NULL);
+        strftime(buf, 50, " %B %d,'%y, %H:%M:%S\r\n", localtime(&seconds));
+        pc.printf("[Time] %s", buf);
+        pc.printf(msg0);
+        pc.printf("%s\r", msg1);
+        wait_counter = 0;
+        while (seconds == time(NULL)){
+            if (pc.readable() == 1){
+                buf[0] = pc.getc();  // dummy read
+                time_enter_mode();
+            }
+            if (userSW == PUSHED_SW){
+                pc.printf(msg2);
+                wait(1.0);
+                myled = 0;
+                goto_standby();
+            }
+            wait(0.05);
+            if (++wait_counter > (2000 / 50)){
+                break;
+            }
+        }
+        uint8_t n = strlen(msg0) + strlen(msg1);
+        for (uint8_t i = 0; i < n; i++){
+            pc.putc(' ');
+        }
+        pc.printf("      \r"); // Not use '\n'
+        myled = !myled;
+    }
+}
+
+void time_enter_mode(void)
+{
+    char *ptr;
+    char linebuf[64];
+
+    pc.printf("\r\nSet time into RTC\r\n");
+    pc.printf(" e.g. >17 1 16 20 55 23 -> January 16th,'17, 20:55:23\r\n");
+    pc.printf(" If time is fine, just hit enter\r\n");
+    pc.putc('>');
+    ptr = linebuf;
+    get_line(ptr, sizeof(linebuf));
+    pc.printf("\r");
+    chk_and_set_time(ptr);
+}
+
+void goto_standby(void)
+{
+    deepsleep();   // Not Standby Mode but Deep Sleep Mode
+}
+
+//  Change string -> integer
+int xatoi (char **str, unsigned long *res)
+{
+    unsigned long val;
+    unsigned char c, radix, s = 0;
+
+    while ((c = **str) == ' ') (*str)++;
+    if (c == '-') {
+        s = 1;
+        c = *(++(*str));
+    }
+    if (c == '0') {
+        c = *(++(*str));
+        if (c <= ' ') {
+            *res = 0;
+            return 1;
+        }
+        if (c == 'x') {
+            radix = 16;
+            c = *(++(*str));
+        } else {
+            if (c == 'b') {
+                radix = 2;
+                c = *(++(*str));
+            } else {
+                if ((c >= '0')&&(c <= '9')) {
+                    radix = 8;
+                }   else {
+                    return 0;
+                }
+            }
+        }
+    } else {
+        if ((c < '1')||(c > '9')) {
+            return 0;
+        }
+        radix = 10;
+    }
+    val = 0;
+    while (c > ' ') {
+        if (c >= 'a') c -= 0x20;
+        c -= '0';
+        if (c >= 17) {
+            c -= 7;
+            if (c <= 9) return 0;
+        }
+        if (c >= radix) return 0;
+        val = val * radix + c;
+        c = *(++(*str));
+    }
+    if (s) val = -val;
+    *res = val;
+    return 1;
+}
+
+//  Get key input data
+void get_line (char *buff, int len)
+{
+    char c;
+    int idx = 0;
+
+    for (;;) {
+        c = pc.getc();
+        if (c == '\r') {
+            buff[idx++] = c;
+            break;
+        }
+        if ((c == '\b') && idx) {
+            idx--;
+            pc.putc(c);
+            pc.putc(' ');
+            pc.putc(c);
+        }
+        if (((uint8_t)c >= ' ') && (idx < len - 1)) {
+            buff[idx++] = c;
+            pc.putc(c);
+        }
+    }
+    buff[idx] = 0;
+    pc.putc('\n');
+}
+
+void chk_and_set_time(char *ptr)
+{
+    unsigned long p1;
+    struct tm t;
+    time_t seconds;
+
+    if (xatoi(&ptr, &p1)) {
+        t.tm_year       = (uint8_t)p1 + 100;
+        pc.printf("Year:%d ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_mon        = (uint8_t)p1 - 1;
+        pc.printf("Month:%d ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_mday       = (uint8_t)p1;
+        pc.printf("Day:%d ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_hour       = (uint8_t)p1;
+        pc.printf("Hour:%d ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_min        = (uint8_t)p1;
+        pc.printf("Min:%d ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_sec        = (uint8_t)p1;
+        pc.printf("Sec: %d \r\n",p1);
+    } else {
+        return;
+    }
+    seconds = mktime(&t);
+    set_time(seconds);
+    // Show Time with several example
+    // ex.1
+    pc.printf(
+        "Date: %04d/%02d/%02d, %02d:%02d:%02d\r\n",
+        t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec
+    );
+#if 0
+    time_t seconds;
+    char buf[40];
+
+    seconds = mktime(&t);
+    // ex.2
+    strftime(buf, 40, "%x %X", localtime(&seconds));
+    pc.printf("Date: %s\r\n", buf);
+    // ex.3
+    strftime(buf, 40, "%I:%M:%S %p (%Y/%m/%d)", localtime(&seconds));
+    pc.printf("Date: %s\r\n", buf);
+    // ex.4
+    strftime(buf, 40, "%B %d,'%y, %H:%M:%S", localtime(&seconds));
+    pc.printf("Date: %s\r\n", buf);
+#endif
+}