Implementaion of a weather station using the BMP180 sensor, nokia N5110 lcd screen and the mbed NXP CPC1768 microcontroller

Dependencies:   BMP180 N5110 PowerControl mbed

Fork of DocTest by Craig Evans

Committer:
FFLopes
Date:
Mon May 11 21:35:53 2015 +0000
Revision:
3:f7036017b319
Parent:
2:afdc5d6ca47f
Really finished

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eencae 0:b85460bc73b9 1 /**
eencae 0:b85460bc73b9 2 @file main.cpp
eencae 0:b85460bc73b9 3
FFLopes 3:f7036017b319 4 @brief Program implementation of the weather station
eencae 0:b85460bc73b9 5
eencae 0:b85460bc73b9 6 */
FFLopes 2:afdc5d6ca47f 7
eencae 0:b85460bc73b9 8 #include "main.h"
eencae 0:b85460bc73b9 9
FFLopes 2:afdc5d6ca47f 10 int main()
FFLopes 2:afdc5d6ca47f 11 {
FFLopes 2:afdc5d6ca47f 12 lcd.init();
FFLopes 2:afdc5d6ca47f 13 isOn=true;
FFLopes 2:afdc5d6ca47f 14 powerSaving();
FFLopes 2:afdc5d6ca47f 15 sensor.init();
eencae 1:6fc14cd8ccf1 16
FFLopes 2:afdc5d6ca47f 17 iO.attach(&ioUpdate, 0.7);
FFLopes 2:afdc5d6ca47f 18 readUpdates.attach(&getMeasurements, 1.0 );
FFLopes 2:afdc5d6ca47f 19 serial.attach(&getTimeUpdate);
FFLopes 2:afdc5d6ca47f 20 enableChange.rise(&enableThresChange);
FFLopes 2:afdc5d6ca47f 21 unitsButton.rise(&unitsChanger);
FFLopes 2:afdc5d6ca47f 22
FFLopes 2:afdc5d6ca47f 23
FFLopes 2:afdc5d6ca47f 24
FFLopes 2:afdc5d6ca47f 25 }
FFLopes 2:afdc5d6ca47f 26
FFLopes 2:afdc5d6ca47f 27 ///Functiion to update the IO
FFLopes 2:afdc5d6ca47f 28 void ioUpdate()
FFLopes 2:afdc5d6ca47f 29 {
FFLopes 2:afdc5d6ca47f 30 formatData();
FFLopes 2:afdc5d6ca47f 31 if(LCDState && !isOn) {
FFLopes 2:afdc5d6ca47f 32 lcd.init();
FFLopes 2:afdc5d6ca47f 33 isOn=true;
FFLopes 2:afdc5d6ca47f 34 } else if ( !LCDState && isOn) {
FFLopes 2:afdc5d6ca47f 35 lcd.turnOff();
FFLopes 2:afdc5d6ca47f 36 isOn=false;
FFLopes 2:afdc5d6ca47f 37 }
FFLopes 2:afdc5d6ca47f 38
FFLopes 2:afdc5d6ca47f 39 ///If the button was pressed to the units be changed the temperature is going to be changed to farenheight and the pressure to atm
FFLopes 2:afdc5d6ca47f 40 if(changeUnits == true) {
FFLopes 2:afdc5d6ca47f 41 lcd.clear();
FFLopes 2:afdc5d6ca47f 42 float temp;
FFLopes 2:afdc5d6ca47f 43 temp = ( measurement.temperature*9.0/5.0) + 32.0;
FFLopes 2:afdc5d6ca47f 44 sprintf(buffer, "%4.2f F", temp);
FFLopes 2:afdc5d6ca47f 45 lcd.printString(buffer,0,0);
FFLopes 2:afdc5d6ca47f 46 sprintf(buffer, "Ra %4.1f-%4.1f F", ( maxTemp*9.0/5.0) + 32.0,( minTemp*9.0/5.0) + 32.0);
FFLopes 2:afdc5d6ca47f 47 lcd.printString(buffer,0,1);
FFLopes 2:afdc5d6ca47f 48 temp=measurement.pressure * 0.000986923267;
FFLopes 2:afdc5d6ca47f 49 sprintf(buffer, "%4.2f atm",temp);
FFLopes 2:afdc5d6ca47f 50 lcd.printString(buffer,0,2);
FFLopes 2:afdc5d6ca47f 51 sprintf(buffer,date);
FFLopes 2:afdc5d6ca47f 52 lcd.printString(buffer,0,3);
FFLopes 2:afdc5d6ca47f 53 }
FFLopes 2:afdc5d6ca47f 54
FFLopes 2:afdc5d6ca47f 55 else {
FFLopes 2:afdc5d6ca47f 56 lcd.clear();
FFLopes 2:afdc5d6ca47f 57 float temp = measurement.temperature;
FFLopes 2:afdc5d6ca47f 58 sprintf(buffer, "%4.2f C", temp);
FFLopes 2:afdc5d6ca47f 59 lcd.printString(buffer,0,0);
FFLopes 2:afdc5d6ca47f 60 sprintf(buffer, "Ra %4.1f-%4.1f C", maxTemp,minTemp);
FFLopes 2:afdc5d6ca47f 61 lcd.printString(buffer,0,1);
FFLopes 2:afdc5d6ca47f 62 temp=measurement.pressure;
FFLopes 2:afdc5d6ca47f 63 sprintf(buffer, "%4.2f mbar",temp);
FFLopes 2:afdc5d6ca47f 64 lcd.printString(buffer,0,2);
FFLopes 2:afdc5d6ca47f 65 sprintf(buffer,date);
FFLopes 2:afdc5d6ca47f 66 lcd.printString(buffer,0,3);
FFLopes 2:afdc5d6ca47f 67 }
FFLopes 2:afdc5d6ca47f 68
FFLopes 2:afdc5d6ca47f 69 ///Here the prediction will be shown to the user
FFLopes 2:afdc5d6ca47f 70 switch(chanceOfWeather)
FFLopes 2:afdc5d6ca47f 71 {
FFLopes 2:afdc5d6ca47f 72 case highGood:
FFLopes 2:afdc5d6ca47f 73 sprintf(buffer,"high of good");
FFLopes 2:afdc5d6ca47f 74 break;
FFLopes 2:afdc5d6ca47f 75
FFLopes 2:afdc5d6ca47f 76 case mediumGood:
FFLopes 2:afdc5d6ca47f 77 sprintf(buffer,"medium of good");
FFLopes 2:afdc5d6ca47f 78 break;
FFLopes 2:afdc5d6ca47f 79
FFLopes 2:afdc5d6ca47f 80 case mediumBad:
FFLopes 2:afdc5d6ca47f 81 sprintf(buffer,"medium of bad");
FFLopes 2:afdc5d6ca47f 82 break;
FFLopes 2:afdc5d6ca47f 83
FFLopes 2:afdc5d6ca47f 84 case highBad:
FFLopes 2:afdc5d6ca47f 85 sprintf(buffer,"high of bad");
FFLopes 2:afdc5d6ca47f 86 break;
FFLopes 2:afdc5d6ca47f 87
FFLopes 2:afdc5d6ca47f 88 case notDefined:
FFLopes 2:afdc5d6ca47f 89 sprintf(buffer,"not decided");
FFLopes 2:afdc5d6ca47f 90 break;
FFLopes 2:afdc5d6ca47f 91
FFLopes 2:afdc5d6ca47f 92 default:
FFLopes 2:afdc5d6ca47f 93 break;
FFLopes 2:afdc5d6ca47f 94
FFLopes 2:afdc5d6ca47f 95
FFLopes 2:afdc5d6ca47f 96 }
FFLopes 2:afdc5d6ca47f 97
FFLopes 2:afdc5d6ca47f 98 lcd.printString(buffer,0,4);
FFLopes 2:afdc5d6ca47f 99
FFLopes 2:afdc5d6ca47f 100 if(logging) {
FFLopes 2:afdc5d6ca47f 101 writeOnFile();
FFLopes 2:afdc5d6ca47f 102 }
FFLopes 2:afdc5d6ca47f 103
FFLopes 2:afdc5d6ca47f 104 checkValues();
FFLopes 2:afdc5d6ca47f 105 changeThreshold(option);
FFLopes 2:afdc5d6ca47f 106
FFLopes 2:afdc5d6ca47f 107 }
FFLopes 2:afdc5d6ca47f 108 ///On this function the ethernet port will be shutdown so we can save energy
FFLopes 2:afdc5d6ca47f 109 void powerSaving()
FFLopes 2:afdc5d6ca47f 110 {
FFLopes 2:afdc5d6ca47f 111 PHY_PowerDown();
FFLopes 2:afdc5d6ca47f 112
FFLopes 2:afdc5d6ca47f 113 }
FFLopes 2:afdc5d6ca47f 114
FFLopes 2:afdc5d6ca47f 115 ///This function will see if the value for temperature is larger them the threshold values assign, if it is a action will take place
FFLopes 2:afdc5d6ca47f 116 void checkValues()
FFLopes 2:afdc5d6ca47f 117 {
FFLopes 2:afdc5d6ca47f 118 if(measurement.temperature>maxTemp) {
FFLopes 2:afdc5d6ca47f 119 highTempAction();
FFLopes 2:afdc5d6ca47f 120 }
FFLopes 2:afdc5d6ca47f 121
FFLopes 2:afdc5d6ca47f 122 else if (measurement.temperature<minTemp) {
FFLopes 2:afdc5d6ca47f 123 lowTempAction();
FFLopes 2:afdc5d6ca47f 124 }
FFLopes 2:afdc5d6ca47f 125
FFLopes 2:afdc5d6ca47f 126 else {
FFLopes 2:afdc5d6ca47f 127 normalTempAction();
FFLopes 2:afdc5d6ca47f 128 }
FFLopes 2:afdc5d6ca47f 129
FFLopes 2:afdc5d6ca47f 130
FFLopes 2:afdc5d6ca47f 131 }
FFLopes 2:afdc5d6ca47f 132 ///With this function we will get the values from the sensor and store in the memory
FFLopes 2:afdc5d6ca47f 133 void getMeasurements()
FFLopes 2:afdc5d6ca47f 134 {
FFLopes 2:afdc5d6ca47f 135
FFLopes 2:afdc5d6ca47f 136 measurement = sensor.readValues();
FFLopes 2:afdc5d6ca47f 137 }
FFLopes 2:afdc5d6ca47f 138
FFLopes 2:afdc5d6ca47f 139 ///Sets the threshold led to high, even though this is a simple action I used a function to makes easier in to scale the code
FFLopes 2:afdc5d6ca47f 140 void highTempAction()
FFLopes 2:afdc5d6ca47f 141 {
FFLopes 2:afdc5d6ca47f 142 maxTempAlert=1;
FFLopes 2:afdc5d6ca47f 143 buzzer=0.01;
FFLopes 2:afdc5d6ca47f 144 }
FFLopes 2:afdc5d6ca47f 145
FFLopes 2:afdc5d6ca47f 146 ///Sets the threshold led to high, even though this is a simple action I used a function to makes easier in to scale the code
FFLopes 2:afdc5d6ca47f 147 void lowTempAction()
FFLopes 2:afdc5d6ca47f 148 {
FFLopes 2:afdc5d6ca47f 149 minTempAlert=1;
FFLopes 2:afdc5d6ca47f 150 buzzer=0.01;
FFLopes 2:afdc5d6ca47f 151 }
FFLopes 2:afdc5d6ca47f 152
FFLopes 2:afdc5d6ca47f 153 ///what it should be done with the temperature is with the boundiaries considered normal
FFLopes 2:afdc5d6ca47f 154 void normalTempAction()
FFLopes 2:afdc5d6ca47f 155 {
FFLopes 2:afdc5d6ca47f 156 maxTempAlert=0;
FFLopes 2:afdc5d6ca47f 157 minTempAlert=0;
FFLopes 2:afdc5d6ca47f 158 buzzer=0;
FFLopes 2:afdc5d6ca47f 159 }
FFLopes 2:afdc5d6ca47f 160
FFLopes 2:afdc5d6ca47f 161 ///Will write both the temperature and the pressure on a csv file
FFLopes 2:afdc5d6ca47f 162 void writeOnFile()
FFLopes 2:afdc5d6ca47f 163 {
FFLopes 2:afdc5d6ca47f 164 FILE *file = fopen("/file/log.csv", "a");
FFLopes 2:afdc5d6ca47f 165 fprintf(file," %s , %f , %f \r\n ",date,measurement.temperature,measurement.pressure); //in C use \r\n instead of only \n to jump lines
FFLopes 2:afdc5d6ca47f 166 fclose(file);
FFLopes 2:afdc5d6ca47f 167
FFLopes 2:afdc5d6ca47f 168 }
FFLopes 2:afdc5d6ca47f 169
FFLopes 2:afdc5d6ca47f 170 ///here we will set the new values of the temperature threshold, that can change from maximun temperature to 0.
FFLopes 2:afdc5d6ca47f 171 void changeThreshold(int op)
FFLopes 2:afdc5d6ca47f 172 {
FFLopes 2:afdc5d6ca47f 173 if(op==changeMaxTemp) {
FFLopes 2:afdc5d6ca47f 174 maxTemp = pot.read() * maxThresTemp;
FFLopes 2:afdc5d6ca47f 175 }
FFLopes 2:afdc5d6ca47f 176 if(op==changeMinTemp) {
FFLopes 2:afdc5d6ca47f 177 minTemp = pot.read() * maxThresTemp;
FFLopes 2:afdc5d6ca47f 178 }
FFLopes 2:afdc5d6ca47f 179
FFLopes 2:afdc5d6ca47f 180 }
FFLopes 2:afdc5d6ca47f 181
FFLopes 2:afdc5d6ca47f 182 ///this function will get the data being transmited in then serial and store in a array, then weill call the setTime function
FFLopes 2:afdc5d6ca47f 183 void getTimeUpdate()
FFLopes 2:afdc5d6ca47f 184 {
FFLopes 2:afdc5d6ca47f 185 serial.gets(rxString,14);
FFLopes 2:afdc5d6ca47f 186 setTime();
FFLopes 2:afdc5d6ca47f 187 }
FFLopes 2:afdc5d6ca47f 188
FFLopes 2:afdc5d6ca47f 189 ///this function is responsible for getting the information stored in the rxstring array by the getTimeUpdate method.
FFLopes 2:afdc5d6ca47f 190 ///Transform in a integer value and store it in the microcontroller
FFLopes 2:afdc5d6ca47f 191 void setTime()
FFLopes 2:afdc5d6ca47f 192 {
FFLopes 2:afdc5d6ca47f 193 int time = atoi(rxString);
FFLopes 2:afdc5d6ca47f 194 set_time(time);
FFLopes 2:afdc5d6ca47f 195 formatData();
FFLopes 2:afdc5d6ca47f 196 serial.printf("the time was updated to %s \n",date);
FFLopes 2:afdc5d6ca47f 197 }
FFLopes 2:afdc5d6ca47f 198
FFLopes 2:afdc5d6ca47f 199 ///This function uses the time sent over the usb an change from UNIX time to a more human readable format, HH:MM:SS DD/MM/YY
FFLopes 2:afdc5d6ca47f 200 void formatData()
FFLopes 2:afdc5d6ca47f 201 {
FFLopes 2:afdc5d6ca47f 202
FFLopes 2:afdc5d6ca47f 203 time_t seconds = time(NULL);
FFLopes 2:afdc5d6ca47f 204 strftime(date,14, "%e/%m %H:%M:%S", localtime(&seconds) );
FFLopes 2:afdc5d6ca47f 205 }
FFLopes 2:afdc5d6ca47f 206
FFLopes 2:afdc5d6ca47f 207 ///Function to be called with the button is pressed and units should be changed
FFLopes 2:afdc5d6ca47f 208 void unitsChanger()
FFLopes 2:afdc5d6ca47f 209 {
FFLopes 2:afdc5d6ca47f 210 changeUnits = !changeUnits;
FFLopes 2:afdc5d6ca47f 211 }
FFLopes 2:afdc5d6ca47f 212
FFLopes 2:afdc5d6ca47f 213 ///This function will be called when the button is pressed and will chose which temperature threshold is going to be changed
FFLopes 2:afdc5d6ca47f 214 void enableThresChange()
FFLopes 2:afdc5d6ca47f 215 {
FFLopes 2:afdc5d6ca47f 216 if( option == dontChangeTemp) {
FFLopes 2:afdc5d6ca47f 217 option = changeMaxTemp;
FFLopes 2:afdc5d6ca47f 218 }
FFLopes 2:afdc5d6ca47f 219 else if (option == changeMaxTemp) {
FFLopes 2:afdc5d6ca47f 220 option = changeMinTemp;
FFLopes 2:afdc5d6ca47f 221 }
FFLopes 2:afdc5d6ca47f 222
FFLopes 2:afdc5d6ca47f 223 else {
FFLopes 2:afdc5d6ca47f 224 option = dontChangeTemp;
FFLopes 2:afdc5d6ca47f 225 }
FFLopes 2:afdc5d6ca47f 226
FFLopes 2:afdc5d6ca47f 227 }
FFLopes 2:afdc5d6ca47f 228
FFLopes 2:afdc5d6ca47f 229 ///On this function the measurement is going to be stored on the vectors, the values are going to be stored for 4 hours so we can see better how the values are changing
FFLopes 2:afdc5d6ca47f 230 ///moreover 4 is divisor of 24
FFLopes 2:afdc5d6ca47f 231 void storeMeasurement()
FFLopes 2:afdc5d6ca47f 232 {
FFLopes 2:afdc5d6ca47f 233 float tempAverage=0;
FFLopes 2:afdc5d6ca47f 234 float pressureAverage=0;
FFLopes 2:afdc5d6ca47f 235
FFLopes 2:afdc5d6ca47f 236
FFLopes 2:afdc5d6ca47f 237 if(minuteCounter<60) {
FFLopes 2:afdc5d6ca47f 238 measurementMinute[minuteCounter] = measurement;
FFLopes 2:afdc5d6ca47f 239 minuteCounter++;
FFLopes 2:afdc5d6ca47f 240 } else if(hourCounter<60) {
FFLopes 2:afdc5d6ca47f 241
FFLopes 2:afdc5d6ca47f 242 int i;
FFLopes 2:afdc5d6ca47f 243 for(i=0; i<minuteCounter; i++) {
FFLopes 2:afdc5d6ca47f 244 tempAverage += measurementMinute[i].temperature;
FFLopes 2:afdc5d6ca47f 245 pressureAverage += measurementMinute[i].pressure;
FFLopes 2:afdc5d6ca47f 246 }
FFLopes 2:afdc5d6ca47f 247 tempAverage = tempAverage / minuteCounter;
FFLopes 2:afdc5d6ca47f 248 pressureAverage = pressureAverage / minuteCounter;
FFLopes 2:afdc5d6ca47f 249 Measurement temp;
FFLopes 2:afdc5d6ca47f 250 temp.pressure = pressureAverage;
FFLopes 2:afdc5d6ca47f 251 temp.temperature = tempAverage;
FFLopes 2:afdc5d6ca47f 252
FFLopes 2:afdc5d6ca47f 253 measurementHour[hourCounter] = temp;
FFLopes 2:afdc5d6ca47f 254 hourCounter++;
FFLopes 2:afdc5d6ca47f 255 minuteCounter=0;
FFLopes 2:afdc5d6ca47f 256 } else if (hoursCounter<4) {
FFLopes 2:afdc5d6ca47f 257
FFLopes 2:afdc5d6ca47f 258 int i;
FFLopes 2:afdc5d6ca47f 259 for(i=0; i<hourCounter; i++) {
FFLopes 2:afdc5d6ca47f 260 tempAverage += measurementHour[i].temperature;
FFLopes 2:afdc5d6ca47f 261 pressureAverage += measurementHour[i].pressure;
FFLopes 2:afdc5d6ca47f 262 }
FFLopes 2:afdc5d6ca47f 263
FFLopes 2:afdc5d6ca47f 264 tempAverage = tempAverage / hourCounter;
FFLopes 2:afdc5d6ca47f 265 pressureAverage = pressureAverage / hourCounter;
FFLopes 2:afdc5d6ca47f 266
FFLopes 2:afdc5d6ca47f 267 Measurement temp;
FFLopes 2:afdc5d6ca47f 268 temp.pressure = pressureAverage;
FFLopes 2:afdc5d6ca47f 269 temp.temperature = tempAverage;
FFLopes 2:afdc5d6ca47f 270
FFLopes 2:afdc5d6ca47f 271 measurementHours[hoursCounter]=temp;
FFLopes 2:afdc5d6ca47f 272 hoursCounter++;
FFLopes 2:afdc5d6ca47f 273 hourCounter=0;
FFLopes 2:afdc5d6ca47f 274
FFLopes 2:afdc5d6ca47f 275 } else {
FFLopes 2:afdc5d6ca47f 276 makePrediction();
FFLopes 2:afdc5d6ca47f 277 hoursCounter = 0;
eencae 0:b85460bc73b9 278 }
eencae 0:b85460bc73b9 279 }
eencae 0:b85460bc73b9 280
FFLopes 2:afdc5d6ca47f 281 ///Function to make the prediction on how the weather is going to be
FFLopes 2:afdc5d6ca47f 282 void makePrediction()
FFLopes 2:afdc5d6ca47f 283 {
FFLopes 2:afdc5d6ca47f 284 bool pressureIncreased = measurementHours[0].pressure<measurementHours[1].pressure && measurementHours[1].pressure<measurementHours[2].pressure &&
FFLopes 2:afdc5d6ca47f 285 measurementHours[2].pressure<measurementHours[3].pressure;
eencae 0:b85460bc73b9 286
FFLopes 2:afdc5d6ca47f 287 bool tempIncreased = measurementHours[0].temperature<measurementHours[1].temperature && measurementHours[1].temperature<measurementHours[2].temperature &&
FFLopes 2:afdc5d6ca47f 288 measurementHours[2].temperature<measurementHours[3].temperature;
FFLopes 2:afdc5d6ca47f 289
FFLopes 2:afdc5d6ca47f 290 if ( pressureIncreased && tempIncreased ) {
FFLopes 2:afdc5d6ca47f 291 chanceOfWeather = highGood;
FFLopes 2:afdc5d6ca47f 292 }
FFLopes 2:afdc5d6ca47f 293
FFLopes 2:afdc5d6ca47f 294 else if ( pressureIncreased || !tempIncreased) {
FFLopes 2:afdc5d6ca47f 295 chanceOfWeather = mediumGood;
FFLopes 2:afdc5d6ca47f 296 }
FFLopes 2:afdc5d6ca47f 297
FFLopes 2:afdc5d6ca47f 298 else if ( !pressureIncreased || tempIncreased) {
FFLopes 2:afdc5d6ca47f 299 chanceOfWeather = mediumBad;
FFLopes 2:afdc5d6ca47f 300 }
FFLopes 2:afdc5d6ca47f 301
FFLopes 2:afdc5d6ca47f 302 else {
FFLopes 2:afdc5d6ca47f 303 chanceOfWeather = highBad;
FFLopes 2:afdc5d6ca47f 304 }
eencae 0:b85460bc73b9 305 }