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
Diff: main.cpp
- Revision:
- 2:afdc5d6ca47f
- Parent:
- 1:6fc14cd8ccf1
- Child:
- 3:f7036017b319
diff -r 6fc14cd8ccf1 -r afdc5d6ca47f main.cpp --- a/main.cpp Wed Mar 11 16:03:08 2015 +0000 +++ b/main.cpp Mon May 11 21:28:14 2015 +0000 @@ -4,22 +4,302 @@ @brief Program implementation */ + #include "main.h" -int main() { +int main() +{ + lcd.init(); + isOn=true; + powerSaving(); + sensor.init(); - /// flash LED in infinite loop - while(1) { - myled = 1; - wait(0.2); - myled = 0; - wait(0.2); + iO.attach(&ioUpdate, 0.7); + readUpdates.attach(&getMeasurements, 1.0 ); + serial.attach(&getTimeUpdate); + enableChange.rise(&enableThresChange); + unitsButton.rise(&unitsChanger); + + + +} + +///Functiion to update the IO +void ioUpdate() +{ + formatData(); + if(LCDState && !isOn) { + lcd.init(); + isOn=true; + } else if ( !LCDState && isOn) { + lcd.turnOff(); + isOn=false; + } + + ///If the button was pressed to the units be changed the temperature is going to be changed to farenheight and the pressure to atm + if(changeUnits == true) { + lcd.clear(); + float temp; + temp = ( measurement.temperature*9.0/5.0) + 32.0; + sprintf(buffer, "%4.2f F", temp); + lcd.printString(buffer,0,0); + sprintf(buffer, "Ra %4.1f-%4.1f F", ( maxTemp*9.0/5.0) + 32.0,( minTemp*9.0/5.0) + 32.0); + lcd.printString(buffer,0,1); + temp=measurement.pressure * 0.000986923267; + sprintf(buffer, "%4.2f atm",temp); + lcd.printString(buffer,0,2); + sprintf(buffer,date); + lcd.printString(buffer,0,3); + } + + else { + lcd.clear(); + float temp = measurement.temperature; + sprintf(buffer, "%4.2f C", temp); + lcd.printString(buffer,0,0); + sprintf(buffer, "Ra %4.1f-%4.1f C", maxTemp,minTemp); + lcd.printString(buffer,0,1); + temp=measurement.pressure; + sprintf(buffer, "%4.2f mbar",temp); + lcd.printString(buffer,0,2); + sprintf(buffer,date); + lcd.printString(buffer,0,3); + } + +///Here the prediction will be shown to the user + switch(chanceOfWeather) + { + case highGood: + sprintf(buffer,"high of good"); + break; + + case mediumGood: + sprintf(buffer,"medium of good"); + break; + + case mediumBad: + sprintf(buffer,"medium of bad"); + break; + + case highBad: + sprintf(buffer,"high of bad"); + break; + + case notDefined: + sprintf(buffer,"not decided"); + break; + + default: + break; + + + } + +lcd.printString(buffer,0,4); + + if(logging) { + writeOnFile(); + } + + checkValues(); + changeThreshold(option); + +} +///On this function the ethernet port will be shutdown so we can save energy +void powerSaving() +{ + PHY_PowerDown(); + +} + +///This function will see if the value for temperature is larger them the threshold values assign, if it is a action will take place +void checkValues() +{ + if(measurement.temperature>maxTemp) { + highTempAction(); + } + + else if (measurement.temperature<minTemp) { + lowTempAction(); + } + + else { + normalTempAction(); + } + + +} +///With this function we will get the values from the sensor and store in the memory +void getMeasurements() +{ + + measurement = sensor.readValues(); +} + +///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 +void highTempAction() +{ + maxTempAlert=1; + buzzer=0.01; +} + +///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 +void lowTempAction() +{ + minTempAlert=1; + buzzer=0.01; +} + +///what it should be done with the temperature is with the boundiaries considered normal +void normalTempAction() +{ + maxTempAlert=0; + minTempAlert=0; + buzzer=0; +} + +///Will write both the temperature and the pressure on a csv file +void writeOnFile() +{ + FILE *file = fopen("/file/log.csv", "a"); + fprintf(file," %s , %f , %f \r\n ",date,measurement.temperature,measurement.pressure); //in C use \r\n instead of only \n to jump lines + fclose(file); + +} + +///here we will set the new values of the temperature threshold, that can change from maximun temperature to 0. +void changeThreshold(int op) +{ + if(op==changeMaxTemp) { + maxTemp = pot.read() * maxThresTemp; + } + if(op==changeMinTemp) { + minTemp = pot.read() * maxThresTemp; + } + +} + +///this function will get the data being transmited in then serial and store in a array, then weill call the setTime function +void getTimeUpdate() +{ + serial.gets(rxString,14); + setTime(); +} + +///this function is responsible for getting the information stored in the rxstring array by the getTimeUpdate method. +///Transform in a integer value and store it in the microcontroller +void setTime() +{ + int time = atoi(rxString); + set_time(time); + formatData(); + serial.printf("the time was updated to %s \n",date); +} + +///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 +void formatData() +{ + + time_t seconds = time(NULL); + strftime(date,14, "%e/%m %H:%M:%S", localtime(&seconds) ); +} + +///Function to be called with the button is pressed and units should be changed +void unitsChanger() +{ + changeUnits = !changeUnits; +} + +///This function will be called when the button is pressed and will chose which temperature threshold is going to be changed +void enableThresChange() +{ + if( option == dontChangeTemp) { + option = changeMaxTemp; + } + else if (option == changeMaxTemp) { + option = changeMinTemp; + } + + else { + option = dontChangeTemp; + } + +} + +///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 +///moreover 4 is divisor of 24 +void storeMeasurement() +{ + float tempAverage=0; + float pressureAverage=0; + + + if(minuteCounter<60) { + measurementMinute[minuteCounter] = measurement; + minuteCounter++; + } else if(hourCounter<60) { + + int i; + for(i=0; i<minuteCounter; i++) { + tempAverage += measurementMinute[i].temperature; + pressureAverage += measurementMinute[i].pressure; + } + tempAverage = tempAverage / minuteCounter; + pressureAverage = pressureAverage / minuteCounter; + Measurement temp; + temp.pressure = pressureAverage; + temp.temperature = tempAverage; + + measurementHour[hourCounter] = temp; + hourCounter++; + minuteCounter=0; + } else if (hoursCounter<4) { + + int i; + for(i=0; i<hourCounter; i++) { + tempAverage += measurementHour[i].temperature; + pressureAverage += measurementHour[i].pressure; + } + + tempAverage = tempAverage / hourCounter; + pressureAverage = pressureAverage / hourCounter; + + Measurement temp; + temp.pressure = pressureAverage; + temp.temperature = tempAverage; + + measurementHours[hoursCounter]=temp; + hoursCounter++; + hourCounter=0; + + } else { + makePrediction(); + hoursCounter = 0; } } +///Function to make the prediction on how the weather is going to be +void makePrediction() +{ + bool pressureIncreased = measurementHours[0].pressure<measurementHours[1].pressure && measurementHours[1].pressure<measurementHours[2].pressure && + measurementHours[2].pressure<measurementHours[3].pressure; -int sum(int a, int b) { - - /// calculate the sum of the two arguments and return - return a + b; + bool tempIncreased = measurementHours[0].temperature<measurementHours[1].temperature && measurementHours[1].temperature<measurementHours[2].temperature && + measurementHours[2].temperature<measurementHours[3].temperature; + + if ( pressureIncreased && tempIncreased ) { + chanceOfWeather = highGood; + } + + else if ( pressureIncreased || !tempIncreased) { + chanceOfWeather = mediumGood; + } + + else if ( !pressureIncreased || tempIncreased) { + chanceOfWeather = mediumBad; + } + + else { + chanceOfWeather = highBad; + } } \ No newline at end of file