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
main.cpp@3:44517d2520e1, 2018-07-04 (annotated)
- Committer:
- daniel_davvid
- Date:
- Wed Jul 04 19:37:10 2018 +0000
- Revision:
- 3:44517d2520e1
- Parent:
- 2:bc1c1f395e9a
Update v1.2
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
daniel_davvid | 0:e42837021e1a | 1 | #include "mbed.h" |
daniel_davvid | 0:e42837021e1a | 2 | |
daniel_davvid | 3:44517d2520e1 | 3 | #define DONT_MOVE 0 |
daniel_davvid | 1:f20e1ea0302e | 4 | #define UPDATE_RTC_TIME 0 |
daniel_davvid | 1:f20e1ea0302e | 5 | #define RTC_TIME 1530462446 |
daniel_davvid | 3:44517d2520e1 | 6 | #define DISPLAY_INTERVAL 0.5f |
daniel_davvid | 3:44517d2520e1 | 7 | #define SUN_POS_INTERVAL 10// one minute for sun position update using |
daniel_davvid | 3:44517d2520e1 | 8 | // the Helios algorithm |
daniel_davvid | 3:44517d2520e1 | 9 | #define PLATFORM_POSITION_POLL_INTERVAL 1 // read platform position sensors |
daniel_davvid | 3:44517d2520e1 | 10 | #define WEATHER_STATE_UPDATE_INTERVAL 1 |
daniel_davvid | 3:44517d2520e1 | 11 | |
daniel_davvid | 1:f20e1ea0302e | 12 | |
daniel_davvid | 0:e42837021e1a | 13 | #ifndef M_PI |
daniel_davvid | 3:44517d2520e1 | 14 | #define M_PI 3.1415926535897932384626433832795028841971693993751058209749445923078164f |
daniel_davvid | 0:e42837021e1a | 15 | #endif |
daniel_davvid | 0:e42837021e1a | 16 | // DS1820 temp sens pin |
daniel_davvid | 0:e42837021e1a | 17 | #define MAX_PROBES 16 |
daniel_davvid | 1:f20e1ea0302e | 18 | #define DATA_PIN A1 |
daniel_davvid | 0:e42837021e1a | 19 | //#define MULTIPLE_PROBES |
daniel_davvid | 0:e42837021e1a | 20 | |
daniel_davvid | 0:e42837021e1a | 21 | #include "BH1750.h" //Light sensor lib |
daniel_davvid | 0:e42837021e1a | 22 | #include "BMP280.h" //Pressure sensor lib |
daniel_davvid | 0:e42837021e1a | 23 | #include "DS1820.h" //Temp sensor lib (One wire) |
daniel_davvid | 0:e42837021e1a | 24 | #include "Helios.h" //Sun tracking algorithm |
daniel_davvid | 0:e42837021e1a | 25 | #include "HMC5983.h" //Compass lib |
daniel_davvid | 0:e42837021e1a | 26 | #include "MAX17043.h" //Fuel gauge sens lib |
daniel_davvid | 0:e42837021e1a | 27 | #include "MPU6050.h" //Accelerometer sensor lib |
daniel_davvid | 0:e42837021e1a | 28 | #include "SHTx/sht15.hpp" //Humidity sens lib |
daniel_davvid | 0:e42837021e1a | 29 | #include "SSD1306.h" //Display lib |
daniel_davvid | 0:e42837021e1a | 30 | #include "stepper.h" //Stepping motor lib. |
daniel_davvid | 0:e42837021e1a | 31 | |
daniel_davvid | 0:e42837021e1a | 32 | Serial pc(USBTX, USBRX); |
daniel_davvid | 3:44517d2520e1 | 33 | //Serial pi(D1, D0); |
daniel_davvid | 0:e42837021e1a | 34 | //Digital pins |
daniel_davvid | 3:44517d2520e1 | 35 | DigitalIn maxAngleLimit(PC_8); |
daniel_davvid | 3:44517d2520e1 | 36 | DigitalIn minAngleLimit(PC_6); |
daniel_davvid | 1:f20e1ea0302e | 37 | DigitalOut swPi(PC_5); |
daniel_davvid | 1:f20e1ea0302e | 38 | DigitalIn pir(PB_12); |
daniel_davvid | 0:e42837021e1a | 39 | //Analog pins |
daniel_davvid | 1:f20e1ea0302e | 40 | AnalogIn waterLevel(A2); |
daniel_davvid | 1:f20e1ea0302e | 41 | AnalogIn crtConsumption(A3); |
daniel_davvid | 0:e42837021e1a | 42 | |
daniel_davvid | 0:e42837021e1a | 43 | // Stepper motor setup |
daniel_davvid | 0:e42837021e1a | 44 | stepper stpCirc(PA_12, NC, NC, NC, PB_1, PB_2); |
daniel_davvid | 3:44517d2520e1 | 45 | stepper stpAngle(PA_11, NC, NC, NC, PB_14, PB_15); |
daniel_davvid | 0:e42837021e1a | 46 | |
daniel_davvid | 0:e42837021e1a | 47 | //DS1820 setup |
daniel_davvid | 0:e42837021e1a | 48 | DS1820* probe[MAX_PROBES]; |
daniel_davvid | 0:e42837021e1a | 49 | |
daniel_davvid | 0:e42837021e1a | 50 | //Helios algorithm |
daniel_davvid | 0:e42837021e1a | 51 | Helios sun; |
daniel_davvid | 0:e42837021e1a | 52 | |
daniel_davvid | 0:e42837021e1a | 53 | // I2C communication setup |
daniel_davvid | 0:e42837021e1a | 54 | I2C i2c1(D14, D15); |
daniel_davvid | 0:e42837021e1a | 55 | I2C i2c2(D3, D6); |
daniel_davvid | 1:f20e1ea0302e | 56 | //I2C i2c3(D5, D7); |
daniel_davvid | 0:e42837021e1a | 57 | |
daniel_davvid | 0:e42837021e1a | 58 | // Maybe change the format |
daniel_davvid | 3:44517d2520e1 | 59 | SHTx::SHT15 sht(D5, D7); |
daniel_davvid | 0:e42837021e1a | 60 | |
daniel_davvid | 0:e42837021e1a | 61 | //I2C 1 sensors |
daniel_davvid | 0:e42837021e1a | 62 | BH1750 bh(i2c1); |
daniel_davvid | 0:e42837021e1a | 63 | BMP280 bmp(i2c1); |
daniel_davvid | 0:e42837021e1a | 64 | HMC5983 compass(i2c1); |
daniel_davvid | 0:e42837021e1a | 65 | MAX17043 fuelGauge(i2c1); |
daniel_davvid | 0:e42837021e1a | 66 | SSD1306 lcd1(&i2c1, 0x78); |
daniel_davvid | 0:e42837021e1a | 67 | |
daniel_davvid | 0:e42837021e1a | 68 | //I2C 2 sensors |
daniel_davvid | 0:e42837021e1a | 69 | SSD1306 lcd2(&i2c2, 0x78); |
daniel_davvid | 0:e42837021e1a | 70 | MPU6050 mpu(i2c2); |
daniel_davvid | 0:e42837021e1a | 71 | |
daniel_davvid | 0:e42837021e1a | 72 | // Timers |
daniel_davvid | 3:44517d2520e1 | 73 | Timer sunPosUpdateTimer; |
daniel_davvid | 3:44517d2520e1 | 74 | Timer platformPositionPollTimer; |
daniel_davvid | 3:44517d2520e1 | 75 | Timer platformRotateTimer; |
daniel_davvid | 3:44517d2520e1 | 76 | Timer panelTiltTimer; |
daniel_davvid | 3:44517d2520e1 | 77 | Timer pirPollTimer; |
daniel_davvid | 3:44517d2520e1 | 78 | Timer weatherStateUpdateTimer; |
daniel_davvid | 0:e42837021e1a | 79 | Timer displayTimer; |
daniel_davvid | 3:44517d2520e1 | 80 | |
daniel_davvid | 0:e42837021e1a | 81 | |
daniel_davvid | 3:44517d2520e1 | 82 | // platform rotate & panel tilt |
daniel_davvid | 3:44517d2520e1 | 83 | // timer intervals |
daniel_davvid | 3:44517d2520e1 | 84 | float platformRotateInterval; |
daniel_davvid | 3:44517d2520e1 | 85 | float panelTiltInterval; |
daniel_davvid | 3:44517d2520e1 | 86 | |
daniel_davvid | 3:44517d2520e1 | 87 | // Accelerometer readings |
daniel_davvid | 0:e42837021e1a | 88 | Vector scaledAccel; |
daniel_davvid | 3:44517d2520e1 | 89 | float vertG; // Z axis component of the g |
daniel_davvid | 3:44517d2520e1 | 90 | float accelDesiredAngle, accelActualAngle; |
daniel_davvid | 0:e42837021e1a | 91 | |
daniel_davvid | 3:44517d2520e1 | 92 | //Compass |
daniel_davvid | 3:44517d2520e1 | 93 | float compassDesiredAngle, compassActualAngle; |
daniel_davvid | 3:44517d2520e1 | 94 | |
daniel_davvid | 3:44517d2520e1 | 95 | |
daniel_davvid | 3:44517d2520e1 | 96 | // PIR state variable and update interval |
daniel_davvid | 1:f20e1ea0302e | 97 | bool pirDetectionOccured = false; |
daniel_davvid | 3:44517d2520e1 | 98 | // 60 seconds warm-up for first update |
daniel_davvid | 1:f20e1ea0302e | 99 | int pirUpdateInterval = 60; |
daniel_davvid | 0:e42837021e1a | 100 | |
daniel_davvid | 3:44517d2520e1 | 101 | // LCD displays current shown page |
daniel_davvid | 3:44517d2520e1 | 102 | int crtPage = 0; |
daniel_davvid | 3:44517d2520e1 | 103 | |
daniel_davvid | 3:44517d2520e1 | 104 | // Auxiliary variables for RTC time |
daniel_davvid | 3:44517d2520e1 | 105 | // readings |
daniel_davvid | 3:44517d2520e1 | 106 | time_t seconds; |
daniel_davvid | 3:44517d2520e1 | 107 | char buffer[32]; |
daniel_davvid | 3:44517d2520e1 | 108 | |
daniel_davvid | 3:44517d2520e1 | 109 | |
daniel_davvid | 3:44517d2520e1 | 110 | //Function forward declarations |
daniel_davvid | 3:44517d2520e1 | 111 | void init(); // setup all devices |
daniel_davvid | 3:44517d2520e1 | 112 | |
daniel_davvid | 3:44517d2520e1 | 113 | float compassAngleDiff(float a, float b); // compute angle difference between |
daniel_davvid | 3:44517d2520e1 | 114 | // the compass read angle and the |
daniel_davvid | 3:44517d2520e1 | 115 | // desired angle |
daniel_davvid | 3:44517d2520e1 | 116 | |
daniel_davvid | 3:44517d2520e1 | 117 | float accelAngleDiff(float a, float b); |
daniel_davvid | 3:44517d2520e1 | 118 | |
daniel_davvid | 3:44517d2520e1 | 119 | int getWaterLevel(); // read the water level sensor |
daniel_davvid | 3:44517d2520e1 | 120 | |
daniel_davvid | 3:44517d2520e1 | 121 | void updatePirState(); // read the PIR state and update |
daniel_davvid | 3:44517d2520e1 | 122 | // state variable |
daniel_davvid | 3:44517d2520e1 | 123 | |
daniel_davvid | 3:44517d2520e1 | 124 | float getCrtConsumption(); // read the current sensor |
daniel_davvid | 0:e42837021e1a | 125 | |
daniel_davvid | 0:e42837021e1a | 126 | int main() |
daniel_davvid | 0:e42837021e1a | 127 | { |
daniel_davvid | 3:44517d2520e1 | 128 | //Sensor variable names |
daniel_davvid | 3:44517d2520e1 | 129 | float lightIntensity; |
daniel_davvid | 3:44517d2520e1 | 130 | float bmpTemp, pressure; |
daniel_davvid | 3:44517d2520e1 | 131 | float humidity, shtTemp; |
daniel_davvid | 3:44517d2520e1 | 132 | float crtConsumption; |
daniel_davvid | 3:44517d2520e1 | 133 | float VCell, SOC; |
daniel_davvid | 3:44517d2520e1 | 134 | float temperature; |
daniel_davvid | 3:44517d2520e1 | 135 | int maxAngle, minAngle; |
daniel_davvid | 3:44517d2520e1 | 136 | // initialize all devices |
daniel_davvid | 3:44517d2520e1 | 137 | init(); |
daniel_davvid | 3:44517d2520e1 | 138 | |
daniel_davvid | 3:44517d2520e1 | 139 | while (1) { |
daniel_davvid | 3:44517d2520e1 | 140 | |
daniel_davvid | 3:44517d2520e1 | 141 | //Helios |
daniel_davvid | 3:44517d2520e1 | 142 | if (sunPosUpdateTimer.read() > SUN_POS_INTERVAL) { |
daniel_davvid | 3:44517d2520e1 | 143 | seconds = time(NULL); |
daniel_davvid | 3:44517d2520e1 | 144 | strftime(buffer, 32, "%H:%M:%S", localtime(&seconds)); |
daniel_davvid | 3:44517d2520e1 | 145 | sun.updatePosition(); |
daniel_davvid | 3:44517d2520e1 | 146 | compassDesiredAngle = sun.azimuth(); |
daniel_davvid | 3:44517d2520e1 | 147 | accelDesiredAngle = sun.elevation(); |
daniel_davvid | 3:44517d2520e1 | 148 | } |
daniel_davvid | 3:44517d2520e1 | 149 | |
daniel_davvid | 3:44517d2520e1 | 150 | if (pirPollTimer.read() > pirUpdateInterval) { |
daniel_davvid | 3:44517d2520e1 | 151 | pirPollTimer.reset(); |
daniel_davvid | 3:44517d2520e1 | 152 | pirUpdateInterval = 1; |
daniel_davvid | 3:44517d2520e1 | 153 | updatePirState(); |
daniel_davvid | 3:44517d2520e1 | 154 | } |
daniel_davvid | 3:44517d2520e1 | 155 | |
daniel_davvid | 3:44517d2520e1 | 156 | if (platformPositionPollTimer.read() > PLATFORM_POSITION_POLL_INTERVAL) { |
daniel_davvid | 3:44517d2520e1 | 157 | platformPositionPollTimer.reset(); |
daniel_davvid | 3:44517d2520e1 | 158 | // read compass |
daniel_davvid | 3:44517d2520e1 | 159 | compassActualAngle = 360-compass.read(); |
daniel_davvid | 3:44517d2520e1 | 160 | |
daniel_davvid | 3:44517d2520e1 | 161 | // read accelerometer |
daniel_davvid | 3:44517d2520e1 | 162 | scaledAccel = mpu.readScaledAccel(); |
daniel_davvid | 3:44517d2520e1 | 163 | vertG = scaledAccel.ZAxis; |
daniel_davvid | 3:44517d2520e1 | 164 | vertG = vertG > 2.0f ? 3.9f - vertG : vertG; |
daniel_davvid | 3:44517d2520e1 | 165 | vertG = vertG < 1.0f ? vertG : 1.0f; |
daniel_davvid | 3:44517d2520e1 | 166 | vertG = vertG > -1.0f ? vertG : -1.0f; |
daniel_davvid | 3:44517d2520e1 | 167 | accelActualAngle = acos(vertG)/M_PI*180.0f; |
daniel_davvid | 3:44517d2520e1 | 168 | } |
daniel_davvid | 3:44517d2520e1 | 169 | |
daniel_davvid | 3:44517d2520e1 | 170 | if (weatherStateUpdateTimer.read() > WEATHER_STATE_UPDATE_INTERVAL) { |
daniel_davvid | 3:44517d2520e1 | 171 | weatherStateUpdateTimer.reset(); |
daniel_davvid | 3:44517d2520e1 | 172 | //DS1820 sensor |
daniel_davvid | 3:44517d2520e1 | 173 | probe[0]->convertTemperature(true, DS1820::all_devices); |
daniel_davvid | 3:44517d2520e1 | 174 | for (int i = 0; i<1; i++) |
daniel_davvid | 3:44517d2520e1 | 175 | pc.printf("Device %d returns %3.1foC\r\n", i, probe[i]->temperature()); |
daniel_davvid | 3:44517d2520e1 | 176 | //SHT15 |
daniel_davvid | 3:44517d2520e1 | 177 | sht.update(); |
daniel_davvid | 3:44517d2520e1 | 178 | sht.setScale(false); |
daniel_davvid | 3:44517d2520e1 | 179 | |
daniel_davvid | 3:44517d2520e1 | 180 | //Sensor data to variables |
daniel_davvid | 3:44517d2520e1 | 181 | lightIntensity = bh.lux()/1.2f; |
daniel_davvid | 3:44517d2520e1 | 182 | bmpTemp = bmp.getTemperature(); |
daniel_davvid | 3:44517d2520e1 | 183 | pressure = bmp.getPressure(); |
daniel_davvid | 3:44517d2520e1 | 184 | shtTemp = sht.getTemperature(); |
daniel_davvid | 3:44517d2520e1 | 185 | humidity = sht.getHumidity(); |
daniel_davvid | 3:44517d2520e1 | 186 | crtConsumption = getCrtConsumption()*1000; |
daniel_davvid | 3:44517d2520e1 | 187 | probe[0]->convertTemperature(true, DS1820::all_devices); |
daniel_davvid | 3:44517d2520e1 | 188 | temperature = probe[0]->temperature(); |
daniel_davvid | 3:44517d2520e1 | 189 | VCell = fuelGauge.getFloatVCell(); |
daniel_davvid | 3:44517d2520e1 | 190 | SOC = fuelGauge.getFloatSOC(); |
daniel_davvid | 3:44517d2520e1 | 191 | maxAngle = maxAngleLimit.read(); |
daniel_davvid | 3:44517d2520e1 | 192 | minAngle = minAngleLimit.read(); |
daniel_davvid | 3:44517d2520e1 | 193 | azimuth = sun.azimuth(); |
daniel_davvid | 3:44517d2520e1 | 194 | elevation = sun.elevation(); |
daniel_davvid | 3:44517d2520e1 | 195 | } |
daniel_davvid | 3:44517d2520e1 | 196 | |
daniel_davvid | 3:44517d2520e1 | 197 | if (platformRotateTimer.read() > platformRotateInterval) { |
daniel_davvid | 3:44517d2520e1 | 198 | platformRotateTimer.reset(); |
daniel_davvid | 3:44517d2520e1 | 199 | // rotate the platform to reach the desired compass |
daniel_davvid | 3:44517d2520e1 | 200 | // indication |
daniel_davvid | 3:44517d2520e1 | 201 | float angleDiff = compassAngleDiff(compassActualAngle, compassDesiredAngle); |
daniel_davvid | 3:44517d2520e1 | 202 | if (abs(angleDiff) > 5) { |
daniel_davvid | 3:44517d2520e1 | 203 | if (!DONT_MOVE) { |
daniel_davvid | 3:44517d2520e1 | 204 | if (angleDiff > 0) { |
daniel_davvid | 3:44517d2520e1 | 205 | stpCirc.step(0, 1, 30000); |
daniel_davvid | 3:44517d2520e1 | 206 | } |
daniel_davvid | 3:44517d2520e1 | 207 | else { |
daniel_davvid | 3:44517d2520e1 | 208 | stpCirc.step(0, 0, 30000); |
daniel_davvid | 3:44517d2520e1 | 209 | } |
daniel_davvid | 3:44517d2520e1 | 210 | } |
daniel_davvid | 3:44517d2520e1 | 211 | } |
daniel_davvid | 3:44517d2520e1 | 212 | |
daniel_davvid | 3:44517d2520e1 | 213 | // change the rotate interval according to angle difference |
daniel_davvid | 3:44517d2520e1 | 214 | // for large differences, make the update interval shorter |
daniel_davvid | 3:44517d2520e1 | 215 | if (abs(angleDiff) > 10) { |
daniel_davvid | 3:44517d2520e1 | 216 | platformRotateInterval = 0.1f; |
daniel_davvid | 3:44517d2520e1 | 217 | } |
daniel_davvid | 3:44517d2520e1 | 218 | else { |
daniel_davvid | 3:44517d2520e1 | 219 | platformRotateInterval = 1.0f; |
daniel_davvid | 3:44517d2520e1 | 220 | } |
daniel_davvid | 3:44517d2520e1 | 221 | } |
daniel_davvid | 3:44517d2520e1 | 222 | |
daniel_davvid | 3:44517d2520e1 | 223 | if (panelTiltTimer.read() > panelTiltInterval) { |
daniel_davvid | 3:44517d2520e1 | 224 | panelTiltTimer.reset(); |
daniel_davvid | 3:44517d2520e1 | 225 | // tilt the panel to reach the desired accelerometer |
daniel_davvid | 3:44517d2520e1 | 226 | // indication |
daniel_davvid | 3:44517d2520e1 | 227 | |
daniel_davvid | 3:44517d2520e1 | 228 | float angleDiff = accelAngleDiff(accelActualAngle, accelDesiredAngle); |
daniel_davvid | 3:44517d2520e1 | 229 | if (abs(angleDiff) > 2) { |
daniel_davvid | 3:44517d2520e1 | 230 | if (!DONT_MOVE) { |
daniel_davvid | 3:44517d2520e1 | 231 | if (angleDiff > 0 && !maxAngleLimit.read()) { |
daniel_davvid | 3:44517d2520e1 | 232 | stpAngle.step(0, 1, 30000); |
daniel_davvid | 3:44517d2520e1 | 233 | } |
daniel_davvid | 3:44517d2520e1 | 234 | else if (!minAngleLimit.read()) { |
daniel_davvid | 3:44517d2520e1 | 235 | stpAngle.step(0, 0, 30000); |
daniel_davvid | 3:44517d2520e1 | 236 | } |
daniel_davvid | 3:44517d2520e1 | 237 | } |
daniel_davvid | 3:44517d2520e1 | 238 | } |
daniel_davvid | 3:44517d2520e1 | 239 | // change the rotate interval according to angle difference |
daniel_davvid | 3:44517d2520e1 | 240 | // for large differences, make the update interval shorter |
daniel_davvid | 3:44517d2520e1 | 241 | if (abs(angleDiff) > 5) { |
daniel_davvid | 3:44517d2520e1 | 242 | panelTiltInterval = 0.1f; |
daniel_davvid | 3:44517d2520e1 | 243 | } |
daniel_davvid | 3:44517d2520e1 | 244 | else { |
daniel_davvid | 3:44517d2520e1 | 245 | panelTiltInterval = 1.0f; |
daniel_davvid | 3:44517d2520e1 | 246 | } |
daniel_davvid | 3:44517d2520e1 | 247 | } |
daniel_davvid | 3:44517d2520e1 | 248 | if (displayTimer.read() > DISPLAY_INTERVAL) { |
daniel_davvid | 3:44517d2520e1 | 249 | displayTimer.reset(); |
daniel_davvid | 3:44517d2520e1 | 250 | pc.printf("UTC time is: %s\n", buffer); |
daniel_davvid | 3:44517d2520e1 | 251 | pc.printf("Sun azimuth: %.2f, elevation: %.2f\n", sun.azimuth(), sun.elevation()); |
daniel_davvid | 3:44517d2520e1 | 252 | pc.printf("Vcell: %.2f\n", VCell); |
daniel_davvid | 3:44517d2520e1 | 253 | pc.printf("Battery: %.2f\n", SOC); |
daniel_davvid | 3:44517d2520e1 | 254 | pc.printf("Temperature [ %3.2f C ]\r\n", shtTemp); |
daniel_davvid | 3:44517d2520e1 | 255 | pc.printf("Humdity [ %3.2f %% ]\r\n\n", humidity); |
daniel_davvid | 3:44517d2520e1 | 256 | pc.printf("Compass: %2.3f\n", compassActualAngle); |
daniel_davvid | 3:44517d2520e1 | 257 | pc.printf("Vertical angle: %1.3f\n", accelActualAngle); |
daniel_davvid | 3:44517d2520e1 | 258 | pc.printf("Intensity: %5.2f lux\n", lightIntensity); |
daniel_davvid | 3:44517d2520e1 | 259 | pc.printf("Temp = %f\t Pres = %f\n", bmpTemp,pressure); |
daniel_davvid | 3:44517d2520e1 | 260 | if (crtPage == 0) { |
daniel_davvid | 3:44517d2520e1 | 261 | lcd1.setPageAddress(0,0); |
daniel_davvid | 3:44517d2520e1 | 262 | lcd1.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 263 | lcd1.printf("Compass: %3.0f", compassActualAngle); |
daniel_davvid | 3:44517d2520e1 | 264 | //lcd.printf("Difference: %f\n", compassAngleDiff(compassActualAngle, compassDesiredAngle)); |
daniel_davvid | 3:44517d2520e1 | 265 | |
daniel_davvid | 3:44517d2520e1 | 266 | lcd1.setPageAddress(1,1); |
daniel_davvid | 3:44517d2520e1 | 267 | lcd1.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 268 | lcd1.printf("Angle: %2.0f", accelActualAngle); |
daniel_davvid | 3:44517d2520e1 | 269 | lcd1.setPageAddress(2,2); |
daniel_davvid | 3:44517d2520e1 | 270 | lcd1.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 271 | lcd1.printf("LUX: %4.0f", lightIntensity); |
daniel_davvid | 3:44517d2520e1 | 272 | lcd1.setPageAddress(3,3); |
daniel_davvid | 3:44517d2520e1 | 273 | lcd1.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 274 | lcd1.printf("Temp: %.1f", bmpTemp); |
daniel_davvid | 3:44517d2520e1 | 275 | lcd1.setPageAddress(4,4); |
daniel_davvid | 3:44517d2520e1 | 276 | lcd1.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 277 | lcd1.printf("Press: %4.f", pressure); |
daniel_davvid | 3:44517d2520e1 | 278 | lcd1.setPageAddress(5,5); |
daniel_davvid | 3:44517d2520e1 | 279 | lcd1.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 280 | lcd1.printf("Max: %d", maxAngle); |
daniel_davvid | 3:44517d2520e1 | 281 | lcd1.setPageAddress(6,6); |
daniel_davvid | 3:44517d2520e1 | 282 | lcd1.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 283 | lcd1.printf("Min: %d", minAngle); |
daniel_davvid | 3:44517d2520e1 | 284 | lcd1.setPageAddress(7,7); |
daniel_davvid | 3:44517d2520e1 | 285 | lcd1.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 286 | lcd1.printf("PIR: %s", pirDetectionOccured ? "DETECTED" : "NOTHING "); |
daniel_davvid | 3:44517d2520e1 | 287 | |
daniel_davvid | 3:44517d2520e1 | 288 | lcd2.setPageAddress(0,0); |
daniel_davvid | 3:44517d2520e1 | 289 | lcd2.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 290 | lcd2.printf("AZMT: %.2f", azimuth); |
daniel_davvid | 3:44517d2520e1 | 291 | lcd2.setPageAddress(1,1); |
daniel_davvid | 3:44517d2520e1 | 292 | lcd2.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 293 | lcd2.printf("ELV: %.2f", elevation); |
daniel_davvid | 3:44517d2520e1 | 294 | |
daniel_davvid | 3:44517d2520e1 | 295 | //MAXI17043 |
daniel_davvid | 3:44517d2520e1 | 296 | lcd2.setPageAddress(2,2); |
daniel_davvid | 3:44517d2520e1 | 297 | lcd2.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 298 | lcd2.printf("Vcell: %.2f\n", VCell); |
daniel_davvid | 3:44517d2520e1 | 299 | lcd2.setPageAddress(3,3); |
daniel_davvid | 3:44517d2520e1 | 300 | lcd2.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 301 | lcd2.printf("Battery: %.2f\n",SOC); |
daniel_davvid | 3:44517d2520e1 | 302 | |
daniel_davvid | 3:44517d2520e1 | 303 | //SHT15 |
daniel_davvid | 3:44517d2520e1 | 304 | lcd2.setPageAddress(4,4); |
daniel_davvid | 3:44517d2520e1 | 305 | lcd2.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 306 | lcd2.printf("Temp: %3.2f C", shtTemp); |
daniel_davvid | 3:44517d2520e1 | 307 | lcd2.setPageAddress(5,5); |
daniel_davvid | 3:44517d2520e1 | 308 | lcd2.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 309 | lcd2.printf("Hum: %3.2f%%", humidity); |
daniel_davvid | 3:44517d2520e1 | 310 | lcd2.setPageAddress(6,6); |
daniel_davvid | 3:44517d2520e1 | 311 | lcd2.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 312 | lcd2.printf("Crt: %03.1fmA", crtConsumption); |
daniel_davvid | 3:44517d2520e1 | 313 | lcd2.setPageAddress(7,7); |
daniel_davvid | 3:44517d2520e1 | 314 | lcd2.setColumnAddress(0,127); |
daniel_davvid | 3:44517d2520e1 | 315 | lcd2.printf("Temp %2.1f C",temperature); |
daniel_davvid | 3:44517d2520e1 | 316 | |
daniel_davvid | 3:44517d2520e1 | 317 | } |
daniel_davvid | 3:44517d2520e1 | 318 | else { |
daniel_davvid | 3:44517d2520e1 | 319 | } |
daniel_davvid | 3:44517d2520e1 | 320 | crtPage = (crtPage + 1) & 1; |
daniel_davvid | 3:44517d2520e1 | 321 | } |
daniel_davvid | 3:44517d2520e1 | 322 | } |
daniel_davvid | 3:44517d2520e1 | 323 | } |
daniel_davvid | 3:44517d2520e1 | 324 | |
daniel_davvid | 3:44517d2520e1 | 325 | void init() |
daniel_davvid | 3:44517d2520e1 | 326 | { |
daniel_davvid | 3:44517d2520e1 | 327 | maxAngleLimit.mode(PullUp); |
daniel_davvid | 3:44517d2520e1 | 328 | minAngleLimit.mode(PullUp); |
daniel_davvid | 1:f20e1ea0302e | 329 | |
daniel_davvid | 1:f20e1ea0302e | 330 | if (UPDATE_RTC_TIME) { |
daniel_davvid | 1:f20e1ea0302e | 331 | set_time(RTC_TIME); |
daniel_davvid | 1:f20e1ea0302e | 332 | } |
daniel_davvid | 1:f20e1ea0302e | 333 | |
daniel_davvid | 1:f20e1ea0302e | 334 | // Stepper drivers setup |
daniel_davvid | 1:f20e1ea0302e | 335 | if (DONT_MOVE) { |
daniel_davvid | 3:44517d2520e1 | 336 | stpAngle.disable(); |
daniel_davvid | 1:f20e1ea0302e | 337 | stpCirc.disable(); |
daniel_davvid | 1:f20e1ea0302e | 338 | } |
daniel_davvid | 1:f20e1ea0302e | 339 | else { |
daniel_davvid | 3:44517d2520e1 | 340 | stpAngle.enable(); |
daniel_davvid | 1:f20e1ea0302e | 341 | stpCirc.enable(); |
daniel_davvid | 1:f20e1ea0302e | 342 | } |
daniel_davvid | 1:f20e1ea0302e | 343 | swPi = 0; |
daniel_davvid | 0:e42837021e1a | 344 | //SHT15 setup |
daniel_davvid | 3:44517d2520e1 | 345 | sht.setOTPReload(false); |
daniel_davvid | 3:44517d2520e1 | 346 | sht.setResolution(true); |
daniel_davvid | 0:e42837021e1a | 347 | |
daniel_davvid | 0:e42837021e1a | 348 | // DS1820 setup |
daniel_davvid | 0:e42837021e1a | 349 | int num_devices = 0; |
daniel_davvid | 0:e42837021e1a | 350 | while(DS1820::unassignedProbe(DATA_PIN)) { |
daniel_davvid | 0:e42837021e1a | 351 | probe[num_devices] = new DS1820(DATA_PIN); |
daniel_davvid | 0:e42837021e1a | 352 | num_devices++; |
daniel_davvid | 0:e42837021e1a | 353 | if (num_devices == MAX_PROBES) |
daniel_davvid | 0:e42837021e1a | 354 | break; |
daniel_davvid | 1:f20e1ea0302e | 355 | } |
daniel_davvid | 0:e42837021e1a | 356 | //MPU setup |
daniel_davvid | 0:e42837021e1a | 357 | while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) { |
daniel_davvid | 0:e42837021e1a | 358 | pc.printf("Could not find a valid MPU6050 sensor, check wiring!\n"); |
daniel_davvid | 0:e42837021e1a | 359 | wait(0.5); |
daniel_davvid | 0:e42837021e1a | 360 | } |
daniel_davvid | 0:e42837021e1a | 361 | mpu.calibrateGyro(); |
daniel_davvid | 0:e42837021e1a | 362 | mpu.setThreshold(3); |
daniel_davvid | 0:e42837021e1a | 363 | |
daniel_davvid | 0:e42837021e1a | 364 | //BMP setup |
daniel_davvid | 0:e42837021e1a | 365 | bmp.initialize(); |
daniel_davvid | 0:e42837021e1a | 366 | //BH setup |
daniel_davvid | 0:e42837021e1a | 367 | bh.init(); |
daniel_davvid | 0:e42837021e1a | 368 | // |
daniel_davvid | 0:e42837021e1a | 369 | compass.init(); |
daniel_davvid | 3:44517d2520e1 | 370 | compassDesiredAngle = 0.0f; |
daniel_davvid | 3:44517d2520e1 | 371 | accelDesiredAngle = 45.0f; |
daniel_davvid | 3:44517d2520e1 | 372 | |
daniel_davvid | 3:44517d2520e1 | 373 | platformRotateInterval = 0.1f; |
daniel_davvid | 3:44517d2520e1 | 374 | panelTiltInterval = 0.1f; |
daniel_davvid | 3:44517d2520e1 | 375 | |
daniel_davvid | 3:44517d2520e1 | 376 | //Timers Start |
daniel_davvid | 3:44517d2520e1 | 377 | platformRotateTimer.start(); |
daniel_davvid | 3:44517d2520e1 | 378 | panelTiltTimer.start(); |
daniel_davvid | 3:44517d2520e1 | 379 | weatherStateUpdateTimer.start(); |
daniel_davvid | 0:e42837021e1a | 380 | displayTimer.start(); |
daniel_davvid | 3:44517d2520e1 | 381 | platformPositionPollTimer.start(); |
daniel_davvid | 1:f20e1ea0302e | 382 | pirPollTimer.start(); |
daniel_davvid | 3:44517d2520e1 | 383 | sunPosUpdateTimer.start(); |
daniel_davvid | 0:e42837021e1a | 384 | } |
daniel_davvid | 0:e42837021e1a | 385 | |
daniel_davvid | 3:44517d2520e1 | 386 | float accelAngleDiff(float a, float b) |
daniel_davvid | 0:e42837021e1a | 387 | { |
daniel_davvid | 3:44517d2520e1 | 388 | float diff = a - b; |
daniel_davvid | 3:44517d2520e1 | 389 | return diff; |
daniel_davvid | 3:44517d2520e1 | 390 | } |
daniel_davvid | 3:44517d2520e1 | 391 | |
daniel_davvid | 3:44517d2520e1 | 392 | float compassAngleDiff(float a, float b) |
daniel_davvid | 3:44517d2520e1 | 393 | { |
daniel_davvid | 3:44517d2520e1 | 394 | float diff = a - b; |
daniel_davvid | 0:e42837021e1a | 395 | |
daniel_davvid | 0:e42837021e1a | 396 | if (diff > 180) |
daniel_davvid | 0:e42837021e1a | 397 | diff -= 360; |
daniel_davvid | 0:e42837021e1a | 398 | if (diff < -180) |
daniel_davvid | 0:e42837021e1a | 399 | diff += 360; |
daniel_davvid | 0:e42837021e1a | 400 | return diff; |
daniel_davvid | 0:e42837021e1a | 401 | } |
daniel_davvid | 0:e42837021e1a | 402 | |
daniel_davvid | 3:44517d2520e1 | 403 | |
daniel_davvid | 1:f20e1ea0302e | 404 | int getWaterLevel(){ |
daniel_davvid | 0:e42837021e1a | 405 | float value; |
daniel_davvid | 0:e42837021e1a | 406 | value = waterLevel.read() *1000; |
daniel_davvid | 0:e42837021e1a | 407 | if (value<=150) { |
daniel_davvid | 0:e42837021e1a | 408 | value=0; |
daniel_davvid | 0:e42837021e1a | 409 | } else if (value>150 && value<=210) { |
daniel_davvid | 0:e42837021e1a | 410 | value=1/4; |
daniel_davvid | 0:e42837021e1a | 411 | } else if (value>210 && value<=250) { |
daniel_davvid | 0:e42837021e1a | 412 | value=1/2; |
daniel_davvid | 0:e42837021e1a | 413 | } else if (value>250 && value<=350) { |
daniel_davvid | 0:e42837021e1a | 414 | value=3/4;; |
daniel_davvid | 0:e42837021e1a | 415 | } else if (value>350) { |
daniel_davvid | 0:e42837021e1a | 416 | value=1; |
daniel_davvid | 0:e42837021e1a | 417 | } |
daniel_davvid | 0:e42837021e1a | 418 | value=value*100; //final data in x% |
daniel_davvid | 0:e42837021e1a | 419 | return value; |
daniel_davvid | 0:e42837021e1a | 420 | } |
daniel_davvid | 0:e42837021e1a | 421 | |
daniel_davvid | 1:f20e1ea0302e | 422 | float getCrtConsumption(){ |
daniel_davvid | 0:e42837021e1a | 423 | //VOUT=Vcc/2+i*VCC/36.7 |
daniel_davvid | 0:e42837021e1a | 424 | //i=36.7*Vout/Vcc-18.3 |
daniel_davvid | 0:e42837021e1a | 425 | |
daniel_davvid | 1:f20e1ea0302e | 426 | float result = 36.7f * crtConsumption.read() - 18.3f; |
daniel_davvid | 1:f20e1ea0302e | 427 | result = result < 0 ? 0.0f : result; |
daniel_davvid | 1:f20e1ea0302e | 428 | |
daniel_davvid | 1:f20e1ea0302e | 429 | return result; |
daniel_davvid | 1:f20e1ea0302e | 430 | } |
daniel_davvid | 1:f20e1ea0302e | 431 | |
daniel_davvid | 1:f20e1ea0302e | 432 | void updatePirState() { |
daniel_davvid | 1:f20e1ea0302e | 433 | pirDetectionOccured = pir.read() != 0; |
daniel_davvid | 0:e42837021e1a | 434 | } |