Weather station project

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

Committer:
daniel_davvid
Date:
Sun Jul 01 12:11:00 2018 +0000
Revision:
0:e42837021e1a
Weather station project based on multiple sensors

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daniel_davvid 0:e42837021e1a 1 #include "mbed.h"
daniel_davvid 0:e42837021e1a 2
daniel_davvid 0:e42837021e1a 3 #ifndef M_PI
daniel_davvid 0:e42837021e1a 4 #define M_PI 3.1415926535897932384626433832795028841971693993751058209749445923078164
daniel_davvid 0:e42837021e1a 5 #endif
daniel_davvid 0:e42837021e1a 6 // DS1820 temp sens pin
daniel_davvid 0:e42837021e1a 7 #define MAX_PROBES 16
daniel_davvid 0:e42837021e1a 8 #define DATA_PIN A0
daniel_davvid 0:e42837021e1a 9 //#define MULTIPLE_PROBES
daniel_davvid 0:e42837021e1a 10
daniel_davvid 0:e42837021e1a 11 #include "BH1750.h" //Light sensor lib
daniel_davvid 0:e42837021e1a 12 #include "BMP280.h" //Pressure sensor lib
daniel_davvid 0:e42837021e1a 13 #include "DS1820.h" //Temp sensor lib (One wire)
daniel_davvid 0:e42837021e1a 14 #include "Helios.h" //Sun tracking algorithm
daniel_davvid 0:e42837021e1a 15 #include "HMC5983.h" //Compass lib
daniel_davvid 0:e42837021e1a 16 #include "MAX17043.h" //Fuel gauge sens lib
daniel_davvid 0:e42837021e1a 17 #include "MPU6050.h" //Accelerometer sensor lib
daniel_davvid 0:e42837021e1a 18 #include "SHTx/sht15.hpp" //Humidity sens lib
daniel_davvid 0:e42837021e1a 19 #include "SSD1306.h" //Display lib
daniel_davvid 0:e42837021e1a 20 #include "stepper.h" //Stepping motor lib.
daniel_davvid 0:e42837021e1a 21
daniel_davvid 0:e42837021e1a 22 Serial pc(USBTX, USBRX);
daniel_davvid 0:e42837021e1a 23 //Digital pins
daniel_davvid 0:e42837021e1a 24
daniel_davvid 0:e42837021e1a 25 //Analog pins
daniel_davvid 0:e42837021e1a 26 AnalogIn waterLevel(A1);
daniel_davvid 0:e42837021e1a 27 AnalogIn currentData(A2);
daniel_davvid 0:e42837021e1a 28
daniel_davvid 0:e42837021e1a 29 // Stepper motor setup
daniel_davvid 0:e42837021e1a 30 stepper stpCirc(PA_12, NC, NC, NC, PB_1, PB_2);
daniel_davvid 0:e42837021e1a 31 stepper stpAngl(PA_11, NC, NC, NC, PB_14, PB_15);
daniel_davvid 0:e42837021e1a 32
daniel_davvid 0:e42837021e1a 33 //DS1820 setup
daniel_davvid 0:e42837021e1a 34 DS1820* probe[MAX_PROBES];
daniel_davvid 0:e42837021e1a 35
daniel_davvid 0:e42837021e1a 36 //Helios algorithm
daniel_davvid 0:e42837021e1a 37 Helios sun;
daniel_davvid 0:e42837021e1a 38
daniel_davvid 0:e42837021e1a 39 // I2C communication setup
daniel_davvid 0:e42837021e1a 40 I2C i2c1(D14, D15);
daniel_davvid 0:e42837021e1a 41 I2C i2c2(D3, D6);
daniel_davvid 0:e42837021e1a 42 I2C i2c3(D5, D7);
daniel_davvid 0:e42837021e1a 43
daniel_davvid 0:e42837021e1a 44 // Maybe change the format
daniel_davvid 0:e42837021e1a 45 SHTx::SHT15 sensor(D5, D7);
daniel_davvid 0:e42837021e1a 46
daniel_davvid 0:e42837021e1a 47 //I2C 1 sensors
daniel_davvid 0:e42837021e1a 48 BH1750 bh(i2c1);
daniel_davvid 0:e42837021e1a 49 BMP280 bmp(i2c1);
daniel_davvid 0:e42837021e1a 50 HMC5983 compass(i2c1);
daniel_davvid 0:e42837021e1a 51 MAX17043 fuelGauge(i2c1);
daniel_davvid 0:e42837021e1a 52 SSD1306 lcd1(&i2c1, 0x78);
daniel_davvid 0:e42837021e1a 53
daniel_davvid 0:e42837021e1a 54 //I2C 2 sensors
daniel_davvid 0:e42837021e1a 55 SSD1306 lcd2(&i2c2, 0x78);
daniel_davvid 0:e42837021e1a 56 MPU6050 mpu(i2c2);
daniel_davvid 0:e42837021e1a 57
daniel_davvid 0:e42837021e1a 58 // Timers
daniel_davvid 0:e42837021e1a 59 Timer displayTimer;
daniel_davvid 0:e42837021e1a 60 Timer stepperRelaxTimer;
daniel_davvid 0:e42837021e1a 61 Timer compassPollTimer;
daniel_davvid 0:e42837021e1a 62
daniel_davvid 0:e42837021e1a 63 //Accel
daniel_davvid 0:e42837021e1a 64 //not needed?
daniel_davvid 0:e42837021e1a 65 Vector rawGyro, normGyro;
daniel_davvid 0:e42837021e1a 66 Vector rawAccel, normAccel;
daniel_davvid 0:e42837021e1a 67 //
daniel_davvid 0:e42837021e1a 68 Vector scaledAccel;
daniel_davvid 0:e42837021e1a 69 float vertG;
daniel_davvid 0:e42837021e1a 70 //Compass
daniel_davvid 0:e42837021e1a 71
daniel_davvid 0:e42837021e1a 72 double desiredAngle, actualAngle;
daniel_davvid 0:e42837021e1a 73
daniel_davvid 0:e42837021e1a 74 //Functions
daniel_davvid 0:e42837021e1a 75 double angleDiff(double a, double b);
daniel_davvid 0:e42837021e1a 76 int waterLevel();
daniel_davvid 0:e42837021e1a 77 int pirDetect();
daniel_davvid 0:e42837021e1a 78 float curentData();
daniel_davvid 0:e42837021e1a 79
daniel_davvid 0:e42837021e1a 80 int main()
daniel_davvid 0:e42837021e1a 81 {
daniel_davvid 0:e42837021e1a 82 //Helios algorithm setup
daniel_davvid 0:e42837021e1a 83 time_t seconds;
daniel_davvid 0:e42837021e1a 84 char buffer[32];
daniel_davvid 0:e42837021e1a 85 set_time(1529836800);
daniel_davvid 0:e42837021e1a 86
daniel_davvid 0:e42837021e1a 87 //Stepper enable
daniel_davvid 0:e42837021e1a 88 stpCirc.enable();
daniel_davvid 0:e42837021e1a 89 stpAngl.enable();
daniel_davvid 0:e42837021e1a 90 //SHT15 setup
daniel_davvid 0:e42837021e1a 91 sensor.setOTPReload(false);
daniel_davvid 0:e42837021e1a 92 sensor.setResolution(true);
daniel_davvid 0:e42837021e1a 93
daniel_davvid 0:e42837021e1a 94 // DS1820 setup
daniel_davvid 0:e42837021e1a 95 int num_devices = 0;
daniel_davvid 0:e42837021e1a 96 while(DS1820::unassignedProbe(DATA_PIN)) {
daniel_davvid 0:e42837021e1a 97 probe[num_devices] = new DS1820(DATA_PIN);
daniel_davvid 0:e42837021e1a 98 num_devices++;
daniel_davvid 0:e42837021e1a 99 if (num_devices == MAX_PROBES)
daniel_davvid 0:e42837021e1a 100 break;
daniel_davvid 0:e42837021e1a 101 //MPU setup
daniel_davvid 0:e42837021e1a 102 while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) {
daniel_davvid 0:e42837021e1a 103 pc.printf("Could not find a valid MPU6050 sensor, check wiring!\n");
daniel_davvid 0:e42837021e1a 104 wait(0.5);
daniel_davvid 0:e42837021e1a 105 }
daniel_davvid 0:e42837021e1a 106 mpu.calibrateGyro();
daniel_davvid 0:e42837021e1a 107 mpu.setThreshold(3);
daniel_davvid 0:e42837021e1a 108
daniel_davvid 0:e42837021e1a 109 //BMP setup
daniel_davvid 0:e42837021e1a 110 bmp.initialize();
daniel_davvid 0:e42837021e1a 111 //BH setup
daniel_davvid 0:e42837021e1a 112 bh.init();
daniel_davvid 0:e42837021e1a 113 //
daniel_davvid 0:e42837021e1a 114 compass.init();
daniel_davvid 0:e42837021e1a 115 desiredAngle = 0.0; //** SET BY HELIOS LIB!!!!**
daniel_davvid 0:e42837021e1a 116
daniel_davvid 0:e42837021e1a 117 //Timers Start
daniel_davvid 0:e42837021e1a 118 displayTimer.start();
daniel_davvid 0:e42837021e1a 119 compassPollTimer.start();
daniel_davvid 0:e42837021e1a 120
daniel_davvid 0:e42837021e1a 121
daniel_davvid 0:e42837021e1a 122 while (1) {
daniel_davvid 0:e42837021e1a 123
daniel_davvid 0:e42837021e1a 124 //Helios
daniel_davvid 0:e42837021e1a 125 seconds = time(NULL);
daniel_davvid 0:e42837021e1a 126 sun.updatePosition();
daniel_davvid 0:e42837021e1a 127 strftime(buffer, 32, "%H:%M:%S", localtime(&seconds));
daniel_davvid 0:e42837021e1a 128
daniel_davvid 0:e42837021e1a 129 //SHT15
daniel_davvid 0:e42837021e1a 130 busy = true;
daniel_davvid 0:e42837021e1a 131 sensor.update();
daniel_davvid 0:e42837021e1a 132 busy = false;
daniel_davvid 0:e42837021e1a 133 sensor.setScale(false);
daniel_davvid 0:e42837021e1a 134
daniel_davvid 0:e42837021e1a 135 //MPU readings
daniel_davvid 0:e42837021e1a 136 // not needed?
daniel_davvid 0:e42837021e1a 137 rawGyro = mpu.readRawGyro();
daniel_davvid 0:e42837021e1a 138 normGyro = mpu.readNormalizeGyro();
daniel_davvid 0:e42837021e1a 139 rawAccel = mpu.readRawAccel();
daniel_davvid 0:e42837021e1a 140 normAccel = mpu.readNormalizeAccel();
daniel_davvid 0:e42837021e1a 141 // (ADD TO A new READ FUNCTION in lib???)
daniel_davvid 0:e42837021e1a 142 scaledAccel = mpu.readScaledAccel();
daniel_davvid 0:e42837021e1a 143 vertG = scaledAccel.ZAxis;
daniel_davvid 0:e42837021e1a 144 vertG = vertG > 2.0f ? 3.9f - vertG : vertG;
daniel_davvid 0:e42837021e1a 145 vertG = vertG < 1.0f ? vertG : 1.0f;
daniel_davvid 0:e42837021e1a 146 vertG = vertG > -1.0f ? vertG : -1.0f;
daniel_davvid 0:e42837021e1a 147
daniel_davvid 0:e42837021e1a 148
daniel_davvid 0:e42837021e1a 149 if (compassPollTimer.read() > 1) {
daniel_davvid 0:e42837021e1a 150 compassPollTimer.reset();
daniel_davvid 0:e42837021e1a 151 actualAngle = 360-compass.read();
daniel_davvid 0:e42837021e1a 152
daniel_davvid 0:e42837021e1a 153 //Helios
daniel_davvid 0:e42837021e1a 154 printf("UTC time is: %s\n", buffer);
daniel_davvid 0:e42837021e1a 155 printf("Sun azimuth: %.2f, elevation: %.2f\n", sun.azimuth(), sun.elevation());
daniel_davvid 0:e42837021e1a 156
daniel_davvid 0:e42837021e1a 157 //MAXI17043
daniel_davvid 0:e42837021e1a 158 pc.printf("Vcell: %.2f\n", fuelGauge.getFloatVCell());
daniel_davvid 0:e42837021e1a 159 pc.printf("Battery: %.2f\n", fuelGauge.getFloatSOC());
daniel_davvid 0:e42837021e1a 160
daniel_davvid 0:e42837021e1a 161 //SHT15
daniel_davvid 0:e42837021e1a 162 pc.printf("Temperature [ %3.2f C ]\r\n", sensor.getTemperature());
daniel_davvid 0:e42837021e1a 163 pc.printf("Humdity [ %3.2f %% ]\r\n\n", sensor.getHumidity());
daniel_davvid 0:e42837021e1a 164
daniel_davvid 0:e42837021e1a 165 //DS1820 sensor
daniel_davvid 0:e42837021e1a 166 probe[0]->convertTemperature(true, DS1820::all_devices);
daniel_davvid 0:e42837021e1a 167 for (int i = 0; i<num_devices; i++)
daniel_davvid 0:e42837021e1a 168 pc.printf("Device %d returns %3.1foC\r\n", i, probe[i]->temperature());
daniel_davvid 0:e42837021e1a 169 //
daniel_davvid 0:e42837021e1a 170
daniel_davvid 0:e42837021e1a 171 lcd.setPageAddress(0,0);
daniel_davvid 0:e42837021e1a 172 lcd.setColumnAddress(0,127);
daniel_davvid 0:e42837021e1a 173 lcd.printf("Compass: %3.0f", actualAngle);
daniel_davvid 0:e42837021e1a 174 pc.printf("Compass: %2.3f\n", actualAngle);
daniel_davvid 0:e42837021e1a 175 //lcd.printf("Difference: %f\n", angleDiff(actualAngle, desiredAngle));
daniel_davvid 0:e42837021e1a 176
daniel_davvid 0:e42837021e1a 177 lcd.setPageAddress(1,1);
daniel_davvid 0:e42837021e1a 178 lcd.setColumnAddress(0,127);
daniel_davvid 0:e42837021e1a 179 lcd.printf("Angle: %2.0f", acos(vertG)/M_PI*180.0f);
daniel_davvid 0:e42837021e1a 180 // lcd.printf("Angle: %2.3f", vertG);
daniel_davvid 0:e42837021e1a 181 pc.printf("Vertical angle: %1.3f\n", acos(vertG)/M_PI*180.0f);
daniel_davvid 0:e42837021e1a 182
daniel_davvid 0:e42837021e1a 183 lcd.setPageAddress(2,2);
daniel_davvid 0:e42837021e1a 184 lcd.setColumnAddress(0,127);
daniel_davvid 0:e42837021e1a 185 lcd.printf("LUX: %4.0f", (bh.lux()/1.2f));
daniel_davvid 0:e42837021e1a 186 pc.printf("Intensity: %5.2f lux\n", (bh.lux()/1.2f));
daniel_davvid 0:e42837021e1a 187
daniel_davvid 0:e42837021e1a 188 pc.printf("Temp = %f\t Pres = %f\n", bmp.getTemperature(),bmp.getPressure());
daniel_davvid 0:e42837021e1a 189 lcd.setPageAddress(3,3);
daniel_davvid 0:e42837021e1a 190 lcd.setColumnAddress(0,127);
daniel_davvid 0:e42837021e1a 191 lcd.printf("Temp: %.1f", bmp.getTemperature());
daniel_davvid 0:e42837021e1a 192 lcd.setPageAddress(4,4);
daniel_davvid 0:e42837021e1a 193 lcd.setColumnAddress(0,127);
daniel_davvid 0:e42837021e1a 194 lcd.printf("Press: %4.f", bmp.getPressure());
daniel_davvid 0:e42837021e1a 195
daniel_davvid 0:e42837021e1a 196
daniel_davvid 0:e42837021e1a 197
daniel_davvid 0:e42837021e1a 198 if (abs(angleDiff(actualAngle, desiredAngle)) > 5) {
daniel_davvid 0:e42837021e1a 199 if (angleDiff(actualAngle, desiredAngle) > 0) {
daniel_davvid 0:e42837021e1a 200 stepper.setDirection(StepperController::DirectionCCW);
daniel_davvid 0:e42837021e1a 201 stpAngl.step(0, 1, 100);
daniel_davvid 0:e42837021e1a 202 }
daniel_davvid 0:e42837021e1a 203 else {
daniel_davvid 0:e42837021e1a 204 stepper.setDirection(StepperController::DirectionCW);
daniel_davvid 0:e42837021e1a 205 stpAngl.step(0, 0, 100);
daniel_davvid 0:e42837021e1a 206 }
daniel_davvid 0:e42837021e1a 207
daniel_davvid 0:e42837021e1a 208 }
daniel_davvid 0:e42837021e1a 209 }
daniel_davvid 0:e42837021e1a 210 }
daniel_davvid 0:e42837021e1a 211 }
daniel_davvid 0:e42837021e1a 212
daniel_davvid 0:e42837021e1a 213 double angleDiff(double a, double b)
daniel_davvid 0:e42837021e1a 214 {
daniel_davvid 0:e42837021e1a 215 double diff = a - b;
daniel_davvid 0:e42837021e1a 216
daniel_davvid 0:e42837021e1a 217 if (diff > 180)
daniel_davvid 0:e42837021e1a 218 diff -= 360;
daniel_davvid 0:e42837021e1a 219 if (diff < -180)
daniel_davvid 0:e42837021e1a 220 diff += 360;
daniel_davvid 0:e42837021e1a 221 return diff;
daniel_davvid 0:e42837021e1a 222 }
daniel_davvid 0:e42837021e1a 223
daniel_davvid 0:e42837021e1a 224 int waterLevel(){
daniel_davvid 0:e42837021e1a 225 float value;
daniel_davvid 0:e42837021e1a 226 value = waterLevel.read() *1000;
daniel_davvid 0:e42837021e1a 227 if (value<=150) {
daniel_davvid 0:e42837021e1a 228 value=0;
daniel_davvid 0:e42837021e1a 229 } else if (value>150 && value<=210) {
daniel_davvid 0:e42837021e1a 230 value=1/4;
daniel_davvid 0:e42837021e1a 231 } else if (value>210 && value<=250) {
daniel_davvid 0:e42837021e1a 232 value=1/2;
daniel_davvid 0:e42837021e1a 233 } else if (value>250 && value<=350) {
daniel_davvid 0:e42837021e1a 234 value=3/4;;
daniel_davvid 0:e42837021e1a 235 } else if (value>350) {
daniel_davvid 0:e42837021e1a 236 value=1;
daniel_davvid 0:e42837021e1a 237 }
daniel_davvid 0:e42837021e1a 238 value=value*100; //final data in x%
daniel_davvid 0:e42837021e1a 239 return value;
daniel_davvid 0:e42837021e1a 240 }
daniel_davvid 0:e42837021e1a 241
daniel_davvid 0:e42837021e1a 242 float currentData(){
daniel_davvid 0:e42837021e1a 243 //VOUT=Vcc/2+i*VCC/36.7
daniel_davvid 0:e42837021e1a 244 //i=36.7*Vout/Vcc-18.3
daniel_davvid 0:e42837021e1a 245
daniel_davvid 0:e42837021e1a 246 float current;
daniel_davvid 0:e42837021e1a 247 current = 36.7*(currentData.read()/3.3)-18.3;//???
daniel_davvid 0:e42837021e1a 248 return current;
daniel_davvid 0:e42837021e1a 249 }