Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of N5110 by
Revision 20:4145b7a59ef7, committed 2015-05-07
- Comitter:
- qk2277
- Date:
- Thu May 07 16:12:53 2015 +0000
- Parent:
- 19:ba8addc061ea
- Commit message:
- the first version of my project
Changed in this revision
| N5110.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/N5110.cpp Thu Apr 23 18:57:52 2015 +0000
+++ b/N5110.cpp Thu May 07 16:12:53 2015 +0000
@@ -4,8 +4,10 @@
@brief Member functions implementations
*/
+
+#include "N5110.h"
#include "mbed.h"
-#include "N5110.h"
+#include "BMP180.h"
N5110::N5110(PinName pwrPin, PinName scePin, PinName rstPin, PinName dcPin, PinName mosiPin, PinName sclkPin, PinName ledPin)
@@ -404,3 +406,317 @@
}
}
+
+
+
+BMP180::BMP180(PinName sdaPin, PinName sclPin)
+{
+ i2c = new I2C(sdaPin,sclPin); // create new I2C instance and initialise
+ i2c->frequency(400000); // I2C Fast Mode - 400kHz
+ leds = new BusOut(LED4,LED3,LED2,LED1);
+}
+
+Measurement BMP180::readValues()
+{
+ // algorithm for taking measurement is taken from datasheet
+ int32_t UT = readUncompensatedTemperatureValue();
+ int32_t UP = readUncompensatedPressureValue();
+ // once you have the uncompensated T and P, you can calculate the true T and P
+ // using the equations from the datasheet
+ int32_t T = calcTrueTemperature(UT);
+ int32_t P = calcTruePressure(UP);
+
+ Measurement measurement;
+ measurement.temperature = T*0.1; // scaled by 0.1 C
+ measurement.pressure = P*0.01; // Put pressure in mb
+
+ return measurement;
+}
+
+int32_t BMP180::readUncompensatedTemperatureValue()
+{
+ // from algorithm in datasheet - p15
+ sendByteToRegister(0x2E,0xF4);
+ wait_ms(5); // 4.5 ms delay for OSS = 1
+ char MSB = readByteFromRegister(0xF6);
+ char LSB = readByteFromRegister(0xF7);
+ // combine in 16-bit value
+ int UT = (MSB << 8) | LSB;
+#ifdef DEBUG
+ UT = 27898; // test data from datasheet
+ printf("****DEBUG MODE****\nUT = %d\n",UT);
+#endif
+ return UT;
+}
+
+int32_t BMP180::readUncompensatedPressureValue()
+{
+ // from datasheet
+ char byte = 0x34 + (oss << 6);
+ sendByteToRegister(byte,0xF4);
+ wait_ms(8); // 7.5 ms delay for OSS = 1
+
+ char MSB = readByteFromRegister(0xF6);
+ char LSB = readByteFromRegister(0xF7);
+ char XLSB = readByteFromRegister(0xF7);
+ int UP = (MSB << 16 | LSB << 8 | XLSB) >> (8 - oss);
+
+#ifdef DEBUG
+ UP = 23843; // test data from datasheet
+ printf("UP = %d\n",UP);
+#endif
+ return UP;
+}
+
+int32_t BMP180::calcTrueTemperature(int32_t UT)
+{
+ // equations from data sheet
+ X1 = ((UT - calibration.AC6)*calibration.AC5) >> 15;
+ X2 = (calibration.MC << 11) / (X1 + calibration.MD);
+ B5 = X1 + X2;
+ int32_t T = (B5 + 8) >> 4;
+#ifdef DEBUG
+ printf("****\nX1=%d\nX2=%d\nB5=%d\nT=%d\n",X1,X2,B5,T);
+#endif
+ return T;
+}
+
+int32_t BMP180::calcTruePressure(int32_t UP)
+{
+ // equations from data sheet
+ B6 = B5 - 4000;
+ X1 = (calibration.B2 * ((B6*B6) >> 12))>>11;
+ X2 = (calibration.AC2*B6)>>11;
+ X3 = X1 + X2;
+ B3 = (((calibration.AC1*4 + X3) << oss)+2)/4;
+#ifdef DEBUG
+ printf("*****\nB6=%d\nX1=%d\nX2=%d\nX3=%d\nB3=%d\n",B6,X1,X2,X3,B3);
+#endif
+ X1 = (calibration.AC3*B6)>>13;
+ X2 = (calibration.B1*((B6*B6)>>12))>>16;
+ X3 = ((X1+X2)+2)/4;
+ B4 = (calibration.AC4*(uint32_t)(X3+32768))>>15;
+#ifdef DEBUG
+ printf("X1=%d\nX2=%d\nX3=%d\nB4=%u\n",X1,X2,X3,B4);
+#endif
+ B7 = ((uint32_t)UP - B3)*(50000>>oss);
+#ifdef DEBUG
+ printf("B7=%u\n",B7);
+#endif
+ int32_t P;
+ if (B7 < 0x80000000)
+ P = (B7*2)/B4;
+ else
+ P = (B7/B4)*2;
+#ifdef DEBUG
+ printf("P=%d\n",P);
+#endif
+ X1 = (P>>8)*(P>>8);
+#ifdef DEBUG
+ printf("X1=%d\n",X1);
+#endif
+ X1 = (X1*3038)>>16;
+#ifdef DEBUG
+ printf("X1=%d\n",X1);
+#endif
+ X2 = (-7357*P)>>16;
+#ifdef DEBUG
+ printf("X2=%d\n",X2);
+#endif
+ P = P + (X1+X2+3791)/16;
+#ifdef DEBUG
+ printf("P=%d\n",P);
+#endif
+
+ return P;
+
+}
+
+// configure the barometer
+void BMP180::init()
+{
+ i2c->frequency(400000); // set Fast Mode I2C frequency
+
+ char data = readByteFromRegister(ID_REG); // Section 4 - datasheet
+ if (data != 0x55) { // if correct ID not found, hang and flash error message
+ error();
+ }
+
+ readCalibrationData();
+
+ oss = 1; // standard power oversampling setting
+
+#ifdef DEBUG
+ oss = 0; // used when testing data sheet example
+#endif
+
+
+}
+
+// Reads factory calibrated data
+void BMP180::readCalibrationData()
+{
+
+ char eeprom[22];
+
+ readBytesFromRegister(EEPROM_REG_ADD,22,eeprom);
+ // store calibration data in structure
+ calibration.AC1 = (int16_t) (eeprom[0] << 8) | eeprom[1];
+ calibration.AC2 = (int16_t) (eeprom[2] << 8) | eeprom[3];
+ calibration.AC3 = (int16_t) (eeprom[4] << 8) | eeprom[5];
+ calibration.AC4 = (uint16_t) (eeprom[6] << 8) | eeprom[7];
+ calibration.AC5 = (uint16_t) (eeprom[8] << 8) | eeprom[9];
+ calibration.AC6 = (uint16_t) (eeprom[10] << 8) | eeprom[11];
+ calibration.B1 = (int16_t) (eeprom[12] << 8) | eeprom[13];
+ calibration.B2 = (int16_t) (eeprom[14] << 8) | eeprom[15];
+ calibration.MB = (int16_t) (eeprom[16] << 8) | eeprom[17];
+ calibration.MC = (int16_t) (eeprom[18] << 8) | eeprom[19];
+ calibration.MD = (int16_t) (eeprom[20] << 8) | eeprom[21];
+
+ // test data from data sheet
+#ifdef DEBUG
+ calibration.AC1 = 408;
+ calibration.AC2 = -72;
+ calibration.AC3 = -14383;
+ calibration.AC4 = 32741;
+ calibration.AC5 = 32757;
+ calibration.AC6 = 23153;
+ calibration.B1 = 6190;
+ calibration.B2 = 4;
+ calibration.MB = -32768;
+ calibration.MC = -8711;
+ calibration.MD = 2868;
+ printf("****EXAMPLE CALIBRATION DATA****\n");
+ printf("AC1=%d\nAC2=%d\nAC3=%d\nAC4=%u\nAC5=%u\nAC6=%u\nB1=%d\nB2=%d\nMB=%d\nMC=%d\nMD=%d\n",
+ calibration.AC1,calibration.AC2,calibration.AC3,calibration.AC4,calibration.AC5,calibration.AC6,
+ calibration.B1,calibration.B2,calibration.MB,calibration.MC,calibration.MD);
+#endif
+}
+
+
+// reads a byte from a specific register
+char BMP180::readByteFromRegister(char reg)
+{
+ int nack = i2c->write(BMP180_W_ADDRESS,®,1,true); // send the register address to the slave
+ if (nack)
+ error(); // if we don't receive acknowledgement, flash error message
+
+ char rx;
+ nack = i2c->read(BMP180_W_ADDRESS,&rx,1); // read a byte from the register and store in buffer
+ if (nack)
+ error(); // if we don't receive acknowledgement, flash error message
+
+ return rx;
+}
+
+// reads a series of bytes, starting from a specific register
+void BMP180::readBytesFromRegister(char reg,int numberOfBytes,char bytes[])
+{
+ int nack = i2c->write(BMP180_W_ADDRESS,®,1,true); // send the slave write address and the configuration register address
+
+ if (nack)
+ error(); // if we don't receive acknowledgement, flash error message
+
+ nack = i2c->read(BMP180_W_ADDRESS,bytes,numberOfBytes); // read bytes
+ if (nack)
+ error(); // if we don't receive acknowledgement, flash error message
+
+}
+
+// sends a byte to a specific register
+void BMP180::sendByteToRegister(char byte,char reg)
+{
+ char data[2];
+ data[0] = reg;
+ data[1] = byte;
+ // send the register address, followed by the data
+ int nack = i2c->write(BMP180_W_ADDRESS,data,2);
+ if (nack)
+ error(); // if we don't receive acknowledgement, flash error message
+
+}
+
+void BMP180::error()
+{
+ while(1) {
+ leds->write(15);
+ wait(0.1);
+ leds->write(0);
+ wait(0.1);
+ }
+}
+
+
+
+
+N5110 lcd(p7,p8,p9,p10,p11,p13,p26);//The ports being connected of the mbed
+BusOut leds(LED4,LED3,LED2,LED1);//The ports being connected of the LCD
+BMP180 bmp180(p28,p27);//The ports being connected to the sensor
+Serial serial(USBTX,USBRX);//Timer set-up tool
+
+
+//Define the variable
+void serialISR();//ISR that is called when serial data is received
+void setTime();// function to set the UNIX time
+int setTimerFlag = 0;// flag for ISR
+char rxString[16];//Create a 16 chars row to display the data
+
+int main()
+{
+ lcd.init();
+ bmp180.init();//Display the word before the sensor data
+ lcd.printString("Weather",0,0);//At the location (0,0),display word "Weather"
+ lcd.printString("Station",1,3);//At the location (1,3),display word "Station"
+ wait(2.0);//The word above stay for 2s
+ lcd.clear();//Clean the display for the continued work
+
+ Measurement measurement;
+
+ serial.attach(&serialISR);//attach serial ISR
+ char t[30];//Create a 30 chars row to display the time
+ while(1) {
+
+ time_t seconds = time(NULL);//get current time
+ // format time into a string (time and date)
+ strftime(t, 30 , "%X %D",localtime(&seconds));//
+ // print over serial
+ serial.printf("Time = %s\n" ,t);//Display the timer
+ lcd.printString(t,0,5);//The location of the timer
+
+ if(setTimerFlag) {// if updated time has been sent
+ setTimerFlag = 0;//clear flag
+ setTime();// update time
+
+ }
+
+ measurement = bmp180.readValues();//
+ char T[14];//Create a 14 chars row to display the temperature
+ int length =sprintf(T,"T = %.2f C",measurement.temperature);//Set up "T = sensor data" as the thing will be shown
+ if (length <= 14)//Judge the length of chars
+ lcd.printString(T,0,1);//The location of the T will be shown
+ char P[14];//Create a 14 chars row to display the pressure
+ length = sprintf(P,"P = %.2f mb",measurement.pressure);//Set up "P = sensor data" as the thing will be shown
+ lcd.printString(P,0,3); //The location of the P will be shown
+ wait(1);//Repeat the circulate each 1s
+ lcd.clear(); //Clear the data for next processing
+ }
+}
+
+
+void setTime()//// print time for debugging
+{
+
+ serial.printf("set_time - %s",rxString);
+ //// atoi() converts a string to an integer
+ int time = atoi(rxString);
+ //update the time
+ set_time(time);
+}
+
+void serialISR()// when a serial interrupt occurs, read rx string into buffer
+{
+
+ serial.gets(rxString,16);
+ //// set flag
+ setTimerFlag = 1;
+}
