/*
Implemented as of now: 4 Gas sensors being read by analog values (They are not being calibrated, values are pure analog).
GPS should be read and written to SD card, pins most probably need changing due to mega problem, check documentation.
SD card string writing needs changes in terms of formatting. DRASTICALLY
To be implemented: Barometer, Pressure, Xbee, Dust Sensor, Etc.
NOTE: This code runs serial at the speed of 115200, so set the reading to that
NOTE2: THE CURRENT CODE DOES NO WRITE THE OPTICAL DUST SENSOR TO THE SD CARD AND POSSIBLY NOT TO SERIAL EITHER! Xbee still not implemented
Sharp pin 1 (V-LED) => 5V (connected to 150ohm resister)
Sharp pin 2 (LED-GND) => Arduino GND pin
Sharp pin 3 (LED) => Arduino pin 2
Sharp pin 4 (S-GND) => Arduino GND pin
Sharp pin 5 (Vo) => Arduino A0 pin
Sharp pin 6 (Vcc) => 5V
Connections for the HTU21D Humidity Sensor
-VCC = 3.3V
-GND = GND
-SDA = A4 (use inline 10k resistor if your board is 5V)
-SCL = A5 (use inline 10k resistor if your board is 5V)
Errors 998 if not sensor is detected. Error 999 if CRC is bad. (HTU21D Humidity Library)
*/
#include <SPI.h> //Include SD reader and writer libraries
#include <SD.h>
//The following are for the HTU21D humidity sensor
#include "HTU21D.h" //The following is the librar for the HTU21D.h humidty sensor
HTU21D myHumidity;
//End of HTU21D humidity sensor
//THE FOLLOWING LIBRARIES ARE USED FOR THE TMP102 Digital Temperature Sensor
#define TMP102_I2C_ADDRESS 72
/* This is the I2C address for our chip.
This value is correct if you tie the ADD0 pin to ground. See the datasheet for some other values. */
//END OF TMP102
#include <SPI.h>> //THESE 2 LIBRARIES ARE FROM THE SHARP SENSOR SOURCECODE http://www.howmuchsnow.com/arduino/airquality/dust.ino
#include <stdlib.h> //WHAT LIBRARY IS THIS?
#include <Adafruit_GPS.h> //Include the Adafruti GPS library
#include <SoftwareSerial.h> // Include the SoftWare serial library (softSerial)
#include <avr/sleep.h> //May be taken out later depending on how the project advances
//The avr/sleep.h function could be used possibly, according to the shield_sdlog example to
//allow the arduino to read the GPS during an interrupt and thus allows the program more 'fredom'. It parses the new NMEA sentence when available and allows to acces the data when desired
SoftwareSerial mySerial(8, 7); //These pins need to be changed for the MEGA, not to mention you need to rewire the pins if using the Ultimate GPS shield. It works with UNO and Duemilanove
Adafruit_GPS GPS(&mySerial); //Uses the Adafruit GPS library to do most of the 'heavy lifting' of the GPS data.
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO false
// set to true to only log to SD when GPS has a fix, for debugging, keep it false
#define LOG_FIXONLY true
#define ledPin 13 //Will maybe take this pin out later
//THE FOLLOWING SECTION IS FOR THE MLP3115A2 ALTITUDE/PRESSURE SENSOR ONLY
#include <Wire.h> // for IIC communication
#define STATUS 0x00
#define OUT_P_MSB 0x01
#define OUT_P_CSB 0x02
#define OUT_P_LSB 0x03
#define OUT_T_MSB 0x04
#define OUT_T_LSB 0x05
#define DR_STATUS 0x06
#define OUT_P_DELTA_MSB 0x07
#define OUT_P_DELTA_CSB 0x08
#define OUT_P_DELTA_LSB 0x09
#define OUT_T_DELTA_MSB 0x0A
#define OUT_T_DELTA_LSB 0x0B
#define WHO_AM_I 0x0C
#define F_STATUS 0x0D
#define F_DATA 0x0E
#define F_SETUP 0x0F
#define TIME_DLY 0x10
#define SYSMOD 0x11
#define INT_SOURCE 0x12
#define PT_DATA_CFG 0x13
#define BAR_IN_MSB 0x14
#define BAR_IN_LSB 0x15
#define P_TGT_MSB 0x16
#define P_TGT_LSB 0x17
#define T_TGT 0x18
#define P_WND_MSB 0x19
#define P_WND_LSB 0x1A
#define T_WND 0x1B
#define P_MIN_MSB 0x1C
#define P_MIN_CSB 0x1D
#define P_MIN_LSB 0x1E
#define T_MIN_MSB 0x1F
#define T_MIN_LSB 0x20
#define P_MAX_MSB 0x21
#define P_MAX_CSB 0x22
#define P_MAX_LSB 0x23
#define T_MAX_MSB 0x24
#define T_MAX_LSB 0x25
#define CTRL_REG1 0x26
#define CTRL_REG2 0x27
#define CTRL_REG3 0x28
#define CTRL_REG4 0x29
#define CTRL_REG5 0x2A
#define OFF_P 0x2B
#define OFF_T 0x2C
#define OFF_H 0x2D
#define MPL3115A2_ADDRESS 0x60 // 7-bit I2C address
long startTime;
//END OF MLP3115A2 Altitude/Pressure Sensor
// These constants won't change. They're used to give names
// to the pins used:
const int analogInPin1 = A0; // Analog input pin that the potentiometer is attached to
const int analogInPin2 = A1;
const int analogInPin3 = A2;
const int analogInPin4 = A3;
const int chipSelect = 53; //This is the SD Pin, may need changing, on Mega its normally pin 53, must be left as output
int SensorValue1 = 0; // value read from the sensor
int SensorValue2 = 1;
int SensorValue3 = 2;
int SensorValue4 = 3;
int sensor1 = analogRead(analogInPin1); //This line needs to be edited as the analog sensors values and readings need to go in here, not at the bottom
int sensor2 = analogRead(analogInPin2);
int sensor3 = analogRead(analogInPin3);
int sensor4 = analogRead(analogInPin4);
//Begin of Dust Sensor Variables===============
int dustPin=0;
int ledPower=2;
int delayTime=280;
int delayTime2=40;
float offTime=9680;
int dustVal=0;
int i=0;
float ppm=0;
char s[32];
float voltage = 0;
float dustdensity = 0;
float ppmpercf = 0;
//End of dust sensor variables=================
File dataFile; //Creates the file from the library and gives it name, changed later in code
// read a Hex value and return the decimal equivalent
uint8_t parseHex(char c) {
if (c < '0')
return 0;
if (c <= '9')
return c - '0';
if (c < 'A')
return 0;
if (c <= 'F')
return (c - 'A')+10;
}
// blink out an error code
void error(uint8_t errno) {
/*
if (SD.errorCode()) {
putstring("SD error: ");
Serial.print(card.errorCode(), HEX);
Serial.print(',');
Serial.println(card.errorData(), HEX);
}
*/
while(1) {
uint8_t i;
for (i=0; i<errno; i++) {
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
}
for (i=errno; i<10; i++) {
delay(200);
}
}
}
//=====================================STAR OF VOID SETUP=====================================================================
void setup() {
//The following is for the HTU21D Humidity sensor
Serial.println("HTU21D Initiated!!");
myHumidity.begin();
//End of HTU21D Humididty Sensor
//The following is for TMP102 temperature sensor
//The following is for TMP102 temperature sensor
//The Following is for the MPL3115A2 Altitude/Pressure Sensor
Wire.begin(); // join i2c bus
// Serial.begin(57600); // start serial for output THIS HAS TO BE SEEN OVER! MIGHT AFFECT CODE SPEED, Its the speed used in the example only
if(IIC_Read(WHO_AM_I) == 196)
Serial.println("MPL3115A2 online!");
else
Serial.println("No response - check connections");
// Configure the sensor
setModeAltimeter(); // Measure altitude above sea level in meters
//setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa
setOversampleRate(7); // Set Oversample to the recommended 128
enableEventFlags(); // Enable all three pressure and temp event flags
//This concludes the MPL3115A2 Altitude/Pressure Sensor Section
// initialize serial communications at 9600 bps:
Serial.begin(115200); //It needs to be so fast in order to read GPS without having to miss values
pinMode(ledPower,OUTPUT); //The LED for Optical Dust sensor activity
i=0; //Sets Sharp optical dust sensor values to 0
ppm =0;//Sets Sharp optical dust sensor values to 0
Serial.println("\r\nUltimate GPSlogger Shield");
pinMode(ledPin, OUTPUT);
Serial.print("Initializing SD card...");
pinMode(SS, OUTPUT); //Make sure that the default chip select pin is set to output, even if you don't use it, it looks weird as SS...
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
//WHATS UP WITH THE TWO LINES ABOVE?!?!?!?! I MIGHT NOT NEED THEM. WHY PIN SS AND PIN 10?!?!!?
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect, 11, 12, 13)) {
Serial.println("Card initialization failed, or not present");
error(2);
// don't do anything more:
while (1) ;
}
Serial.println("card initialized.");
char filename[15];
strcpy(filename, "GPSLOG00.TXT");
for (uint8_t i = 0; i < 100; i++) {
filename[6] = '0' + i/10;
filename[7] = '0' + i%10;
// create if does not exist, do not open existing, write, sync after write
if (! SD.exists(filename)) {
break;
}
}
// Open up the file we're going to log to!
dataFile = SD.open("DatalLog.txt", FILE_WRITE);
if (! dataFile) {
Serial.println("error opening datalog.txt");
// Wait forever since we can't write data
while (1) ;
}
// connect to the GPS at the desired rate
GPS.begin(9600);
// uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
// uncomment this line to turn on only the "minimum recommended" data
//GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
// For logging data, we don't suggest using anything but either RMC only or RMC+GGA
// to keep the log files at a reasonable size
// Set the update rate
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 or 5 Hz update rate
// Turn off updates on antenna status, if the firmware permits it
GPS.sendCommand(PGCMD_NOANTENNA);
Serial.println("Ready!");
}
//=====================================STAR OF VOID LOOP=====================================================================
void loop() {
//This is for the HTU21D Humidty Sensor
float humd = myHumidity.readHumidity();
float temp = myHumidity.readTemperature();
Serial.print("Time:");
Serial.print(millis());
Serial.print(" Temperature:");
Serial.print(temp, 1);
Serial.print("C");
Serial.print(" Humidity:");
Serial.print(humd, 1);
Serial.print("%");
Serial.println();
delay(1000);
//This si the end for the HTU21D Humidity Sensor
//This is for the TMP102 Tempreature Sensor
getTemp102();
delay(5000); //wait 5 seconds before printing our next set of readings.
//End of TMP102 Temperature sensor
//This section is dedicated to the Sharp optical dust sensor
i=i+1;
digitalWrite(ledPower,LOW); // power on the LED
delayMicroseconds(delayTime);
dustVal=analogRead(dustPin); // read the dust value
ppm = ppm+dustVal;
delayMicroseconds(delayTime2);
digitalWrite(ledPower,HIGH); // turn the LED off
delayMicroseconds(offTime);
// if you're not connected, and ten seconds have passed since
// your last connection, then connect again and send data:
voltage = ppm/i*0.0049;
dustdensity = 0.17*voltage-0.1;
ppmpercf = (voltage-0.0256)*120000;
if (ppmpercf < 0)
ppmpercf = 0;
if (dustdensity < 0 )
dustdensity = 0;
if (dustdensity > 0.5)
dustdensity = 0.5;
String dataString = ""; //CREATES A STRING FOR THE OPTICAL DUST SENSOR
dataString += dtostrf(voltage, 9, 4, s);
dataString += ",";
dataString += dtostrf(dustdensity, 5, 2, s);
dataString += ",";
dataString += dtostrf(ppmpercf, 8, 0, s);
i=0;
ppm=0;
Serial.println(dataString);
delay(1000);
//End of sharp optical dust sensor section
char c = GPS.read();
if (GPSECHO)
if (c) Serial.print(c);
// if a sentence is received, we can check the checksum, parse it...
if (GPS.newNMEAreceived()) {
// a tricky thing here is if we print the NMEA sentence, or data
// we end up not listening and catching other sentences!
// so be very wary if using OUTPUT_ALLDATA and trying to print out data
//Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
return; // we can fail to parse a sentence in which case we should just wait for another
// Sentence parsed!
Serial.println("OK");
if (LOG_FIXONLY && !GPS.fix) {
Serial.print("No Fix");
return;
}
// Rad. lets log it!
Serial.println("Log");
char *stringptr = GPS.lastNMEA();
uint8_t stringsize = strlen(stringptr);
if (stringsize != dataFile.write((uint8_t *)stringptr, stringsize)) //write the string to the SD file
error(4);
if (strstr(stringptr, "RMC")) dataFile.flush();
Serial.println();
// make a string for assembling the data to log:
String dataString = "";
dataFile.println(dataString);
// print to the serial port too:
Serial.println(dataString);
// read the analog in value:
SensorValue1 = analogRead(analogInPin1);
dataString += String(sensor1);
delay(10); //Wiat 10 milliseconds before reading next value so the analog-to-digital converter can settle after reading
SensorValue2 = analogRead(analogInPin2);
dataString += String(sensor2);
delay(10); //Wiat 10 milliseconds before reading next value so the analog-to-digital converter can settle after reading
SensorValue3 = analogRead(analogInPin3);
dataString += String(sensor3);
delay(10); //Wiat 10 milliseconds before reading next value so the analog-to-digital converter can settle after reading
SensorValue4 = analogRead(analogInPin4);
dataString += String(sensor4);
delay(10); //Wiat 10 milliseconds before reading next value so the analog-to-digital converter can settle after reading
// print the results to the serial monitor:
Serial.print("sensor1 = " );
Serial.println(SensorValue1);
Serial.print("sensor2 = " );
Serial.println(SensorValue2);
Serial.print("sensor3 = " );
Serial.println(SensorValue3);
Serial.print("sensor4 = " );
Serial.println(SensorValue4);
// The following line will 'save' the file to the SD card after every
// line of data - this will use more power and slow down how much data
// you can read but it's safer!
// If you want to speed up the system, remove the call to flush() and it
// will save the file only every 512 bytes - every time a sector on the
// SD card is filled with data.
dataFile.flush();
// Take 1 measurement every 500 milliseconds
delay(500);
}
//THIS IS THE PART OF THE CODE FOR THE MPL3115A2 Pressure sensor
startTime = millis();
float altitude = readAltitude();
Serial.print("Altitude(m):");
Serial.print(altitude, 2);
//altitude = readAltitudeFt();
//Serial.print(" Altitude(ft):");
//Serial.print(altitude, 2);
/*float pressure = readPressure();
Serial.print(" Pressure(Pa):");
Serial.println(pressure, 2);*/
//float temperature = readTemp();
//Serial.print(" Temp(c):");
//Serial.print(temperature, 2);
//float temperature = readTempF();
//Serial.print(" Temp(f):");
//Serial.print(temperature, 2);
Serial.print(" time diff:");
Serial.print(millis() - startTime);
Serial.println();
//delay(1);
}
//Returns the number of meters above sea level
float readAltitude()
{
toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading
//Wait for PDR bit, indicates we have new pressure data
int counter = 0;
while( (IIC_Read(STATUS) & (1<<1)) == 0)
{
if(++counter > 100) return(-999); //Error out
delay(1);
}
// Read pressure registers
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(OUT_P_MSB); // Address of data to get
Wire.endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
Wire.requestFrom(MPL3115A2_ADDRESS, 3); // Request three bytes
//Wait for data to become available
counter = 0;
while(Wire.available() < 3)
{
if(counter++ > 100) return(-999); //Error out
delay(1);
}
byte msb, csb, lsb;
msb = Wire.read();
csb = Wire.read();
lsb = Wire.read();
toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading
// The least significant bytes l_altitude and l_temp are 4-bit,
// fractional values, so you must cast the calulation in (float),
// shift the value over 4 spots to the right and divide by 16 (since
// there are 16 values in 4-bits).
float tempcsb = (lsb>>4)/16.0;
float altitude = (float)( (msb << 8) | csb) + tempcsb;
return(altitude);
}
//Returns the number of feet above sea level
float readAltitudeFt()
{
return(readAltitude() * 3.28084);
}
//Reads the current pressure in Pa
//Unit must be set in barometric pressure mode
float readPressure()
{
toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading
//Wait for PDR bit, indicates we have new pressure data
int counter = 0;
while( (IIC_Read(STATUS) & (1<<2)) == 0)
{
if(++counter > 100) return(-999); //Error out
delay(1);
}
// Read pressure registers
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(OUT_P_MSB); // Address of data to get
Wire.endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
Wire.requestFrom(MPL3115A2_ADDRESS, 3); // Request three bytes
//Wait for data to become available
counter = 0;
while(Wire.available() < 3)
{
if(counter++ > 100) return(-999); //Error out
delay(1);
}
byte msb, csb, lsb;
msb = Wire.read();
csb = Wire.read();
lsb = Wire.read();
toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading
// Pressure comes back as a left shifted 20 bit number
long pressure_whole = (long)msb<<16 | (long)csb<<8 | (long)lsb;
pressure_whole >>= 6; //Pressure is an 18 bit number with 2 bits of decimal. Get rid of decimal portion.
lsb &= 0b00110000; //Bits 5/4 represent the fractional component
lsb >>= 4; //Get it right aligned
float pressure_decimal = (float)lsb/4.0; //Turn it into fraction
float pressure = (float)pressure_whole + pressure_decimal;
return(pressure);
}
float readTemp()
{
toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading
//Wait for TDR bit, indicates we have new temp data
int counter = 0;
while( (IIC_Read(STATUS) & (1<<1)) == 0)
{
if(++counter > 100) return(-999); //Error out
delay(1);
}
// Read temperature registers
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(OUT_T_MSB); // Address of data to get
Wire.endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
Wire.requestFrom(MPL3115A2_ADDRESS, 2); // Request two bytes
//Wait for data to become available
counter = 0;
while(Wire.available() < 2)
{
if(++counter > 100) return(-999); //Error out
delay(1);
}
byte msb, lsb;
msb = Wire.read();
lsb = Wire.read();
// The least significant bytes l_altitude and l_temp are 4-bit,
// fractional values, so you must cast the calulation in (float),
// shift the value over 4 spots to the right and divide by 16 (since
// there are 16 values in 4-bits).
float templsb = (lsb>>4)/16.0; //temp, fraction of a degree
float temperature = (float)(msb + templsb);
return(temperature);
}
//Give me temperature in fahrenheit!
float readTempF()
{
return((readTemp() * 9.0)/ 5.0 + 32.0); // Convert celsius to fahrenheit
}
//Sets the mode to Barometer
//CTRL_REG1, ALT bit
void setModeBarometer()
{
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting &= ~(1<<7); //Clear ALT bit
IIC_Write(CTRL_REG1, tempSetting);
}
//Sets the mode to Altimeter
//CTRL_REG1, ALT bit
void setModeAltimeter()
{
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting |= (1<<7); //Set ALT bit
IIC_Write(CTRL_REG1, tempSetting);
}
//Puts the sensor in standby mode
//This is needed so that we can modify the major control registers
void setModeStandby()
{
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting &= ~(1<<0); //Clear SBYB bit for Standby mode
IIC_Write(CTRL_REG1, tempSetting);
}
//Puts the sensor in active mode
//This is needed so that we can modify the major control registers
void setModeActive()
{
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting |= (1<<0); //Set SBYB bit for Active mode
IIC_Write(CTRL_REG1, tempSetting);
}
//Setup FIFO mode to one of three modes. See page 26, table 31
//From user jr4284
void setFIFOMode(byte f_Mode)
{
if (f_Mode > 3) f_Mode = 3; // FIFO value cannot exceed 3.
f_Mode <<= 6; // Shift FIFO byte left 6 to put it in bits 6, 7.
byte tempSetting = IIC_Read(F_SETUP); //Read current settings
tempSetting &= ~(3<<6); // clear bits 6, 7
tempSetting |= f_Mode; //Mask in new FIFO bits
IIC_Write(F_SETUP, tempSetting);
}
//Call with a rate from 0 to 7. See page 33 for table of ratios.
//Sets the over sample rate. Datasheet calls for 128 but you can set it
//from 1 to 128 samples. The higher the oversample rate the greater
//the time between data samples.
void setOversampleRate(byte sampleRate)
{
if(sampleRate > 7) sampleRate = 7; //OS cannot be larger than 0b.0111
sampleRate <<= 3; //Align it for the CTRL_REG1 register
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting &= 0b11000111; //Clear out old OS bits
tempSetting |= sampleRate; //Mask in new OS bits
IIC_Write(CTRL_REG1, tempSetting);
}
//Clears then sets the OST bit which causes the sensor to immediately take another reading
//Needed to sample faster than 1Hz
void toggleOneShot(void)
{
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting &= ~(1<<1); //Clear OST bit
IIC_Write(CTRL_REG1, tempSetting);
tempSetting = IIC_Read(CTRL_REG1); //Read current settings to be safe
tempSetting |= (1<<1); //Set OST bit
IIC_Write(CTRL_REG1, tempSetting);
}
//Enables the pressure and temp measurement event flags so that we can
//test against them. This is recommended in datasheet during setup.
void enableEventFlags()
{
IIC_Write(PT_DATA_CFG, 0x07); // Enable all three pressure and temp event flags
}
// These are the two I2C functions in this sketch.
byte IIC_Read(byte regAddr)
{
// This function reads one byte over IIC
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(regAddr); // Address of CTRL_REG1
Wire.endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
Wire.requestFrom(MPL3115A2_ADDRESS, 1); // Request the data...
return Wire.read();
}
void IIC_Write(byte regAddr, byte value)
{
// This function writes one byto over IIC
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(regAddr);
Wire.write(value);
Wire.endTransmission(true);
}
//This is for the TMP102 Digital Thermometer
void getTemp102(){
byte firstbyte, secondbyte; //these are the bytes we read from the TMP102 temperature registers
int val; /* an int is capable of storing two bytes, this is where we "chuck" the two bytes together. */
float convertedtemp; /* We then need to multiply our two bytes by a scaling factor, mentioned in the datasheet. */
float correctedtemp;
// The sensor overreads (?)
/* Reset the register pointer (by default it is ready to read temperatures)
You can alter it to a writeable register and alter some of the configuration -
the sensor is capable of alerting you if the temperature is above or below a specified threshold. */
Wire.beginTransmission(TMP102_I2C_ADDRESS); //Say hi to the sensor.
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(TMP102_I2C_ADDRESS, 2);
Wire.endTransmission();
firstbyte = (Wire.read());
/*read the TMP102 datasheet - here we read one byte from
each of the temperature registers on the TMP102*/
secondbyte = (Wire.read());
/*The first byte contains the most significant bits, and
the second the less significant */
val = ((firstbyte) << 4);
/* MSB */
val |= (secondbyte >> 4);
/* LSB is ORed into the second 4 bits of our byte.
Bitwise maths is a bit funky, but there's a good tutorial on the playground*/
convertedtemp = val*0.0625;
correctedtemp = convertedtemp - 5;
/* See the above note on overreading */
Serial.print("firstbyte is ");
Serial.print("\t");
Serial.println(firstbyte, BIN);
Serial.print("secondbyte is ");
Serial.print("\t");
Serial.println(secondbyte, BIN);
Serial.print("Concatenated byte is ");
Serial.print("\t");
Serial.println(val, BIN);
Serial.print("Converted temp is ");
Serial.print("\t");
Serial.println(val*0.0625);
Serial.print("Corrected temp is ");
Serial.print("\t");
Serial.println(correctedtemp);
Serial.println();
}
/* End code */
Implemented as of now: 4 Gas sensors being read by analog values (They are not being calibrated, values are pure analog).
GPS should be read and written to SD card, pins most probably need changing due to mega problem, check documentation.
SD card string writing needs changes in terms of formatting. DRASTICALLY
To be implemented: Barometer, Pressure, Xbee, Dust Sensor, Etc.
NOTE: This code runs serial at the speed of 115200, so set the reading to that
NOTE2: THE CURRENT CODE DOES NO WRITE THE OPTICAL DUST SENSOR TO THE SD CARD AND POSSIBLY NOT TO SERIAL EITHER! Xbee still not implemented
Sharp pin 1 (V-LED) => 5V (connected to 150ohm resister)
Sharp pin 2 (LED-GND) => Arduino GND pin
Sharp pin 3 (LED) => Arduino pin 2
Sharp pin 4 (S-GND) => Arduino GND pin
Sharp pin 5 (Vo) => Arduino A0 pin
Sharp pin 6 (Vcc) => 5V
Connections for the HTU21D Humidity Sensor
-VCC = 3.3V
-GND = GND
-SDA = A4 (use inline 10k resistor if your board is 5V)
-SCL = A5 (use inline 10k resistor if your board is 5V)
Errors 998 if not sensor is detected. Error 999 if CRC is bad. (HTU21D Humidity Library)
*/
#include <SPI.h> //Include SD reader and writer libraries
#include <SD.h>
//The following are for the HTU21D humidity sensor
#include "HTU21D.h" //The following is the librar for the HTU21D.h humidty sensor
HTU21D myHumidity;
//End of HTU21D humidity sensor
//THE FOLLOWING LIBRARIES ARE USED FOR THE TMP102 Digital Temperature Sensor
#define TMP102_I2C_ADDRESS 72
/* This is the I2C address for our chip.
This value is correct if you tie the ADD0 pin to ground. See the datasheet for some other values. */
//END OF TMP102
#include <SPI.h>> //THESE 2 LIBRARIES ARE FROM THE SHARP SENSOR SOURCECODE http://www.howmuchsnow.com/arduino/airquality/dust.ino
#include <stdlib.h> //WHAT LIBRARY IS THIS?
#include <Adafruit_GPS.h> //Include the Adafruti GPS library
#include <SoftwareSerial.h> // Include the SoftWare serial library (softSerial)
#include <avr/sleep.h> //May be taken out later depending on how the project advances
//The avr/sleep.h function could be used possibly, according to the shield_sdlog example to
//allow the arduino to read the GPS during an interrupt and thus allows the program more 'fredom'. It parses the new NMEA sentence when available and allows to acces the data when desired
SoftwareSerial mySerial(8, 7); //These pins need to be changed for the MEGA, not to mention you need to rewire the pins if using the Ultimate GPS shield. It works with UNO and Duemilanove
Adafruit_GPS GPS(&mySerial); //Uses the Adafruit GPS library to do most of the 'heavy lifting' of the GPS data.
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO false
// set to true to only log to SD when GPS has a fix, for debugging, keep it false
#define LOG_FIXONLY true
#define ledPin 13 //Will maybe take this pin out later
//THE FOLLOWING SECTION IS FOR THE MLP3115A2 ALTITUDE/PRESSURE SENSOR ONLY
#include <Wire.h> // for IIC communication
#define STATUS 0x00
#define OUT_P_MSB 0x01
#define OUT_P_CSB 0x02
#define OUT_P_LSB 0x03
#define OUT_T_MSB 0x04
#define OUT_T_LSB 0x05
#define DR_STATUS 0x06
#define OUT_P_DELTA_MSB 0x07
#define OUT_P_DELTA_CSB 0x08
#define OUT_P_DELTA_LSB 0x09
#define OUT_T_DELTA_MSB 0x0A
#define OUT_T_DELTA_LSB 0x0B
#define WHO_AM_I 0x0C
#define F_STATUS 0x0D
#define F_DATA 0x0E
#define F_SETUP 0x0F
#define TIME_DLY 0x10
#define SYSMOD 0x11
#define INT_SOURCE 0x12
#define PT_DATA_CFG 0x13
#define BAR_IN_MSB 0x14
#define BAR_IN_LSB 0x15
#define P_TGT_MSB 0x16
#define P_TGT_LSB 0x17
#define T_TGT 0x18
#define P_WND_MSB 0x19
#define P_WND_LSB 0x1A
#define T_WND 0x1B
#define P_MIN_MSB 0x1C
#define P_MIN_CSB 0x1D
#define P_MIN_LSB 0x1E
#define T_MIN_MSB 0x1F
#define T_MIN_LSB 0x20
#define P_MAX_MSB 0x21
#define P_MAX_CSB 0x22
#define P_MAX_LSB 0x23
#define T_MAX_MSB 0x24
#define T_MAX_LSB 0x25
#define CTRL_REG1 0x26
#define CTRL_REG2 0x27
#define CTRL_REG3 0x28
#define CTRL_REG4 0x29
#define CTRL_REG5 0x2A
#define OFF_P 0x2B
#define OFF_T 0x2C
#define OFF_H 0x2D
#define MPL3115A2_ADDRESS 0x60 // 7-bit I2C address
long startTime;
//END OF MLP3115A2 Altitude/Pressure Sensor
// These constants won't change. They're used to give names
// to the pins used:
const int analogInPin1 = A0; // Analog input pin that the potentiometer is attached to
const int analogInPin2 = A1;
const int analogInPin3 = A2;
const int analogInPin4 = A3;
const int chipSelect = 53; //This is the SD Pin, may need changing, on Mega its normally pin 53, must be left as output
int SensorValue1 = 0; // value read from the sensor
int SensorValue2 = 1;
int SensorValue3 = 2;
int SensorValue4 = 3;
int sensor1 = analogRead(analogInPin1); //This line needs to be edited as the analog sensors values and readings need to go in here, not at the bottom
int sensor2 = analogRead(analogInPin2);
int sensor3 = analogRead(analogInPin3);
int sensor4 = analogRead(analogInPin4);
//Begin of Dust Sensor Variables===============
int dustPin=0;
int ledPower=2;
int delayTime=280;
int delayTime2=40;
float offTime=9680;
int dustVal=0;
int i=0;
float ppm=0;
char s[32];
float voltage = 0;
float dustdensity = 0;
float ppmpercf = 0;
//End of dust sensor variables=================
File dataFile; //Creates the file from the library and gives it name, changed later in code
// read a Hex value and return the decimal equivalent
uint8_t parseHex(char c) {
if (c < '0')
return 0;
if (c <= '9')
return c - '0';
if (c < 'A')
return 0;
if (c <= 'F')
return (c - 'A')+10;
}
// blink out an error code
void error(uint8_t errno) {
/*
if (SD.errorCode()) {
putstring("SD error: ");
Serial.print(card.errorCode(), HEX);
Serial.print(',');
Serial.println(card.errorData(), HEX);
}
*/
while(1) {
uint8_t i;
for (i=0; i<errno; i++) {
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
}
for (i=errno; i<10; i++) {
delay(200);
}
}
}
//=====================================STAR OF VOID SETUP=====================================================================
void setup() {
//The following is for the HTU21D Humidity sensor
Serial.println("HTU21D Initiated!!");
myHumidity.begin();
//End of HTU21D Humididty Sensor
//The following is for TMP102 temperature sensor
//The following is for TMP102 temperature sensor
//The Following is for the MPL3115A2 Altitude/Pressure Sensor
Wire.begin(); // join i2c bus
// Serial.begin(57600); // start serial for output THIS HAS TO BE SEEN OVER! MIGHT AFFECT CODE SPEED, Its the speed used in the example only
if(IIC_Read(WHO_AM_I) == 196)
Serial.println("MPL3115A2 online!");
else
Serial.println("No response - check connections");
// Configure the sensor
setModeAltimeter(); // Measure altitude above sea level in meters
//setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa
setOversampleRate(7); // Set Oversample to the recommended 128
enableEventFlags(); // Enable all three pressure and temp event flags
//This concludes the MPL3115A2 Altitude/Pressure Sensor Section
// initialize serial communications at 9600 bps:
Serial.begin(115200); //It needs to be so fast in order to read GPS without having to miss values
pinMode(ledPower,OUTPUT); //The LED for Optical Dust sensor activity
i=0; //Sets Sharp optical dust sensor values to 0
ppm =0;//Sets Sharp optical dust sensor values to 0
Serial.println("\r\nUltimate GPSlogger Shield");
pinMode(ledPin, OUTPUT);
Serial.print("Initializing SD card...");
pinMode(SS, OUTPUT); //Make sure that the default chip select pin is set to output, even if you don't use it, it looks weird as SS...
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
//WHATS UP WITH THE TWO LINES ABOVE?!?!?!?! I MIGHT NOT NEED THEM. WHY PIN SS AND PIN 10?!?!!?
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect, 11, 12, 13)) {
Serial.println("Card initialization failed, or not present");
error(2);
// don't do anything more:
while (1) ;
}
Serial.println("card initialized.");
char filename[15];
strcpy(filename, "GPSLOG00.TXT");
for (uint8_t i = 0; i < 100; i++) {
filename[6] = '0' + i/10;
filename[7] = '0' + i%10;
// create if does not exist, do not open existing, write, sync after write
if (! SD.exists(filename)) {
break;
}
}
// Open up the file we're going to log to!
dataFile = SD.open("DatalLog.txt", FILE_WRITE);
if (! dataFile) {
Serial.println("error opening datalog.txt");
// Wait forever since we can't write data
while (1) ;
}
// connect to the GPS at the desired rate
GPS.begin(9600);
// uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
// uncomment this line to turn on only the "minimum recommended" data
//GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
// For logging data, we don't suggest using anything but either RMC only or RMC+GGA
// to keep the log files at a reasonable size
// Set the update rate
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 or 5 Hz update rate
// Turn off updates on antenna status, if the firmware permits it
GPS.sendCommand(PGCMD_NOANTENNA);
Serial.println("Ready!");
}
//=====================================STAR OF VOID LOOP=====================================================================
void loop() {
//This is for the HTU21D Humidty Sensor
float humd = myHumidity.readHumidity();
float temp = myHumidity.readTemperature();
Serial.print("Time:");
Serial.print(millis());
Serial.print(" Temperature:");
Serial.print(temp, 1);
Serial.print("C");
Serial.print(" Humidity:");
Serial.print(humd, 1);
Serial.print("%");
Serial.println();
delay(1000);
//This si the end for the HTU21D Humidity Sensor
//This is for the TMP102 Tempreature Sensor
getTemp102();
delay(5000); //wait 5 seconds before printing our next set of readings.
//End of TMP102 Temperature sensor
//This section is dedicated to the Sharp optical dust sensor
i=i+1;
digitalWrite(ledPower,LOW); // power on the LED
delayMicroseconds(delayTime);
dustVal=analogRead(dustPin); // read the dust value
ppm = ppm+dustVal;
delayMicroseconds(delayTime2);
digitalWrite(ledPower,HIGH); // turn the LED off
delayMicroseconds(offTime);
// if you're not connected, and ten seconds have passed since
// your last connection, then connect again and send data:
voltage = ppm/i*0.0049;
dustdensity = 0.17*voltage-0.1;
ppmpercf = (voltage-0.0256)*120000;
if (ppmpercf < 0)
ppmpercf = 0;
if (dustdensity < 0 )
dustdensity = 0;
if (dustdensity > 0.5)
dustdensity = 0.5;
String dataString = ""; //CREATES A STRING FOR THE OPTICAL DUST SENSOR
dataString += dtostrf(voltage, 9, 4, s);
dataString += ",";
dataString += dtostrf(dustdensity, 5, 2, s);
dataString += ",";
dataString += dtostrf(ppmpercf, 8, 0, s);
i=0;
ppm=0;
Serial.println(dataString);
delay(1000);
//End of sharp optical dust sensor section
char c = GPS.read();
if (GPSECHO)
if (c) Serial.print(c);
// if a sentence is received, we can check the checksum, parse it...
if (GPS.newNMEAreceived()) {
// a tricky thing here is if we print the NMEA sentence, or data
// we end up not listening and catching other sentences!
// so be very wary if using OUTPUT_ALLDATA and trying to print out data
//Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
return; // we can fail to parse a sentence in which case we should just wait for another
// Sentence parsed!
Serial.println("OK");
if (LOG_FIXONLY && !GPS.fix) {
Serial.print("No Fix");
return;
}
// Rad. lets log it!
Serial.println("Log");
char *stringptr = GPS.lastNMEA();
uint8_t stringsize = strlen(stringptr);
if (stringsize != dataFile.write((uint8_t *)stringptr, stringsize)) //write the string to the SD file
error(4);
if (strstr(stringptr, "RMC")) dataFile.flush();
Serial.println();
// make a string for assembling the data to log:
String dataString = "";
dataFile.println(dataString);
// print to the serial port too:
Serial.println(dataString);
// read the analog in value:
SensorValue1 = analogRead(analogInPin1);
dataString += String(sensor1);
delay(10); //Wiat 10 milliseconds before reading next value so the analog-to-digital converter can settle after reading
SensorValue2 = analogRead(analogInPin2);
dataString += String(sensor2);
delay(10); //Wiat 10 milliseconds before reading next value so the analog-to-digital converter can settle after reading
SensorValue3 = analogRead(analogInPin3);
dataString += String(sensor3);
delay(10); //Wiat 10 milliseconds before reading next value so the analog-to-digital converter can settle after reading
SensorValue4 = analogRead(analogInPin4);
dataString += String(sensor4);
delay(10); //Wiat 10 milliseconds before reading next value so the analog-to-digital converter can settle after reading
// print the results to the serial monitor:
Serial.print("sensor1 = " );
Serial.println(SensorValue1);
Serial.print("sensor2 = " );
Serial.println(SensorValue2);
Serial.print("sensor3 = " );
Serial.println(SensorValue3);
Serial.print("sensor4 = " );
Serial.println(SensorValue4);
// The following line will 'save' the file to the SD card after every
// line of data - this will use more power and slow down how much data
// you can read but it's safer!
// If you want to speed up the system, remove the call to flush() and it
// will save the file only every 512 bytes - every time a sector on the
// SD card is filled with data.
dataFile.flush();
// Take 1 measurement every 500 milliseconds
delay(500);
}
//THIS IS THE PART OF THE CODE FOR THE MPL3115A2 Pressure sensor
startTime = millis();
float altitude = readAltitude();
Serial.print("Altitude(m):");
Serial.print(altitude, 2);
//altitude = readAltitudeFt();
//Serial.print(" Altitude(ft):");
//Serial.print(altitude, 2);
/*float pressure = readPressure();
Serial.print(" Pressure(Pa):");
Serial.println(pressure, 2);*/
//float temperature = readTemp();
//Serial.print(" Temp(c):");
//Serial.print(temperature, 2);
//float temperature = readTempF();
//Serial.print(" Temp(f):");
//Serial.print(temperature, 2);
Serial.print(" time diff:");
Serial.print(millis() - startTime);
Serial.println();
//delay(1);
}
//Returns the number of meters above sea level
float readAltitude()
{
toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading
//Wait for PDR bit, indicates we have new pressure data
int counter = 0;
while( (IIC_Read(STATUS) & (1<<1)) == 0)
{
if(++counter > 100) return(-999); //Error out
delay(1);
}
// Read pressure registers
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(OUT_P_MSB); // Address of data to get
Wire.endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
Wire.requestFrom(MPL3115A2_ADDRESS, 3); // Request three bytes
//Wait for data to become available
counter = 0;
while(Wire.available() < 3)
{
if(counter++ > 100) return(-999); //Error out
delay(1);
}
byte msb, csb, lsb;
msb = Wire.read();
csb = Wire.read();
lsb = Wire.read();
toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading
// The least significant bytes l_altitude and l_temp are 4-bit,
// fractional values, so you must cast the calulation in (float),
// shift the value over 4 spots to the right and divide by 16 (since
// there are 16 values in 4-bits).
float tempcsb = (lsb>>4)/16.0;
float altitude = (float)( (msb << 8) | csb) + tempcsb;
return(altitude);
}
//Returns the number of feet above sea level
float readAltitudeFt()
{
return(readAltitude() * 3.28084);
}
//Reads the current pressure in Pa
//Unit must be set in barometric pressure mode
float readPressure()
{
toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading
//Wait for PDR bit, indicates we have new pressure data
int counter = 0;
while( (IIC_Read(STATUS) & (1<<2)) == 0)
{
if(++counter > 100) return(-999); //Error out
delay(1);
}
// Read pressure registers
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(OUT_P_MSB); // Address of data to get
Wire.endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
Wire.requestFrom(MPL3115A2_ADDRESS, 3); // Request three bytes
//Wait for data to become available
counter = 0;
while(Wire.available() < 3)
{
if(counter++ > 100) return(-999); //Error out
delay(1);
}
byte msb, csb, lsb;
msb = Wire.read();
csb = Wire.read();
lsb = Wire.read();
toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading
// Pressure comes back as a left shifted 20 bit number
long pressure_whole = (long)msb<<16 | (long)csb<<8 | (long)lsb;
pressure_whole >>= 6; //Pressure is an 18 bit number with 2 bits of decimal. Get rid of decimal portion.
lsb &= 0b00110000; //Bits 5/4 represent the fractional component
lsb >>= 4; //Get it right aligned
float pressure_decimal = (float)lsb/4.0; //Turn it into fraction
float pressure = (float)pressure_whole + pressure_decimal;
return(pressure);
}
float readTemp()
{
toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading
//Wait for TDR bit, indicates we have new temp data
int counter = 0;
while( (IIC_Read(STATUS) & (1<<1)) == 0)
{
if(++counter > 100) return(-999); //Error out
delay(1);
}
// Read temperature registers
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(OUT_T_MSB); // Address of data to get
Wire.endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
Wire.requestFrom(MPL3115A2_ADDRESS, 2); // Request two bytes
//Wait for data to become available
counter = 0;
while(Wire.available() < 2)
{
if(++counter > 100) return(-999); //Error out
delay(1);
}
byte msb, lsb;
msb = Wire.read();
lsb = Wire.read();
// The least significant bytes l_altitude and l_temp are 4-bit,
// fractional values, so you must cast the calulation in (float),
// shift the value over 4 spots to the right and divide by 16 (since
// there are 16 values in 4-bits).
float templsb = (lsb>>4)/16.0; //temp, fraction of a degree
float temperature = (float)(msb + templsb);
return(temperature);
}
//Give me temperature in fahrenheit!
float readTempF()
{
return((readTemp() * 9.0)/ 5.0 + 32.0); // Convert celsius to fahrenheit
}
//Sets the mode to Barometer
//CTRL_REG1, ALT bit
void setModeBarometer()
{
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting &= ~(1<<7); //Clear ALT bit
IIC_Write(CTRL_REG1, tempSetting);
}
//Sets the mode to Altimeter
//CTRL_REG1, ALT bit
void setModeAltimeter()
{
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting |= (1<<7); //Set ALT bit
IIC_Write(CTRL_REG1, tempSetting);
}
//Puts the sensor in standby mode
//This is needed so that we can modify the major control registers
void setModeStandby()
{
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting &= ~(1<<0); //Clear SBYB bit for Standby mode
IIC_Write(CTRL_REG1, tempSetting);
}
//Puts the sensor in active mode
//This is needed so that we can modify the major control registers
void setModeActive()
{
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting |= (1<<0); //Set SBYB bit for Active mode
IIC_Write(CTRL_REG1, tempSetting);
}
//Setup FIFO mode to one of three modes. See page 26, table 31
//From user jr4284
void setFIFOMode(byte f_Mode)
{
if (f_Mode > 3) f_Mode = 3; // FIFO value cannot exceed 3.
f_Mode <<= 6; // Shift FIFO byte left 6 to put it in bits 6, 7.
byte tempSetting = IIC_Read(F_SETUP); //Read current settings
tempSetting &= ~(3<<6); // clear bits 6, 7
tempSetting |= f_Mode; //Mask in new FIFO bits
IIC_Write(F_SETUP, tempSetting);
}
//Call with a rate from 0 to 7. See page 33 for table of ratios.
//Sets the over sample rate. Datasheet calls for 128 but you can set it
//from 1 to 128 samples. The higher the oversample rate the greater
//the time between data samples.
void setOversampleRate(byte sampleRate)
{
if(sampleRate > 7) sampleRate = 7; //OS cannot be larger than 0b.0111
sampleRate <<= 3; //Align it for the CTRL_REG1 register
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting &= 0b11000111; //Clear out old OS bits
tempSetting |= sampleRate; //Mask in new OS bits
IIC_Write(CTRL_REG1, tempSetting);
}
//Clears then sets the OST bit which causes the sensor to immediately take another reading
//Needed to sample faster than 1Hz
void toggleOneShot(void)
{
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting &= ~(1<<1); //Clear OST bit
IIC_Write(CTRL_REG1, tempSetting);
tempSetting = IIC_Read(CTRL_REG1); //Read current settings to be safe
tempSetting |= (1<<1); //Set OST bit
IIC_Write(CTRL_REG1, tempSetting);
}
//Enables the pressure and temp measurement event flags so that we can
//test against them. This is recommended in datasheet during setup.
void enableEventFlags()
{
IIC_Write(PT_DATA_CFG, 0x07); // Enable all three pressure and temp event flags
}
// These are the two I2C functions in this sketch.
byte IIC_Read(byte regAddr)
{
// This function reads one byte over IIC
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(regAddr); // Address of CTRL_REG1
Wire.endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
Wire.requestFrom(MPL3115A2_ADDRESS, 1); // Request the data...
return Wire.read();
}
void IIC_Write(byte regAddr, byte value)
{
// This function writes one byto over IIC
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(regAddr);
Wire.write(value);
Wire.endTransmission(true);
}
//This is for the TMP102 Digital Thermometer
void getTemp102(){
byte firstbyte, secondbyte; //these are the bytes we read from the TMP102 temperature registers
int val; /* an int is capable of storing two bytes, this is where we "chuck" the two bytes together. */
float convertedtemp; /* We then need to multiply our two bytes by a scaling factor, mentioned in the datasheet. */
float correctedtemp;
// The sensor overreads (?)
/* Reset the register pointer (by default it is ready to read temperatures)
You can alter it to a writeable register and alter some of the configuration -
the sensor is capable of alerting you if the temperature is above or below a specified threshold. */
Wire.beginTransmission(TMP102_I2C_ADDRESS); //Say hi to the sensor.
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(TMP102_I2C_ADDRESS, 2);
Wire.endTransmission();
firstbyte = (Wire.read());
/*read the TMP102 datasheet - here we read one byte from
each of the temperature registers on the TMP102*/
secondbyte = (Wire.read());
/*The first byte contains the most significant bits, and
the second the less significant */
val = ((firstbyte) << 4);
/* MSB */
val |= (secondbyte >> 4);
/* LSB is ORed into the second 4 bits of our byte.
Bitwise maths is a bit funky, but there's a good tutorial on the playground*/
convertedtemp = val*0.0625;
correctedtemp = convertedtemp - 5;
/* See the above note on overreading */
Serial.print("firstbyte is ");
Serial.print("\t");
Serial.println(firstbyte, BIN);
Serial.print("secondbyte is ");
Serial.print("\t");
Serial.println(secondbyte, BIN);
Serial.print("Concatenated byte is ");
Serial.print("\t");
Serial.println(val, BIN);
Serial.print("Converted temp is ");
Serial.print("\t");
Serial.println(val*0.0625);
Serial.print("Corrected temp is ");
Serial.print("\t");
Serial.println(correctedtemp);
Serial.println();
}
/* End code */