Weather station project
Dependencies: BH1750 BMP280 DS1820 HMC5983 Helios MAX17043 MPU6050 SHTx SSD1306_I2C A4988_stepper mbed
Revision 0:e42837021e1a, committed 2018-07-01
- 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
--- /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 +}