#include <Wire.h>
// From the datasheet the BMP module address LSB distinguishes
// between read (1) and write (0) operations, corresponding to
// address 0x91 (read) and 0x90 (write).
// shift the address 1 bit right (0x91 or 0x90), the Wire library only needs the 7
// most significant bits for the address 0x91 >> 1 = 0x48
// 0x90 >> 1 = 0x48 (72)
int sensorAddress = 0x91 >> 1; // From datasheet sensor address is 0x91
// shift the address 1 bit right, the Wire library only needs the 7
// most significant bits for the address
byte msb;
byte lsb;
int temperature;
void setup()
{
Serial.begin(9600); // start serial communication at 9600bps
Wire.begin(); // join i2c bus (address optional for master)
}
void loop()
{
// step 1: request reading from sensor
Wire.requestFrom(sensorAddress,2);
if (2 <= Wire.available()) // if two bytes were received
{
msb = Wire.read(); // receive high byte (full degrees)
lsb = Wire.read(); // receive low byte (fraction degrees)
temperature = ((msb) << 4); // MSB
temperature |= (lsb >> 4); // LSB
Serial.print("Temperature: ");
Serial.println(temperature*0.0625);
}
delay(500); // wait for half a second
} void temperatura(void)
{
int sensorAddress = 0x91 >> 1;
char msb;
char lsb;
int temperature=0;
TRISDbits.TRISD6=1;
TRISDbits.TRISD5=1;
OpenI2C1( MASTER, SLEW_OFF);
StartI2C2();
WriteI2C1(sensorAddress);
WriteI2C1(2);
StopI2C1();
if ( DataRdyI2C1() )
{
// receive high byte (full degrees)
msb = ReadI2C2(); // receive high byte (full degrees)
lsb = ReadI2C2(); // receive low byte (fraction degrees)
temperature = ((msb) << 4); // MSB
temperature |= (lsb >> 4); // LSB
temperature = temperature*0.0625
//vGLCDTexto(45,42,"T:",ARIAL,1,1);
deco(43, temperature);
}
}, void temperatura(void)
{
char temperature;
TRISDbits.TRISD6=1;
TRISDbits.TRISD5=1;
OpenI2C2(MASTER,SLEW_OFF);
//SSP1ADD =11;
temperature=tmp102read();
Delay10KTCYx(100); //delay de 500ms
}
char tmp102read(void)
{
char msb, lsb;
char temp;
StartI2C2() ;
IdleI2C2() ;
WriteI2C2(TMP_WR); //We want to write a value to the TMP
IdleI2C2();
WriteI2C2(TEMP_REG); //Set pointer regster to temperature register (it's already there by default, but you never know)
IdleI2C2();
StartI2C2() ;
WriteI2C2(TMP_RD); // Read from this I2C address, R/*W Set
IdleI2C2();
transpc('1');
AckI2C2();
IdleI2C2();
msb = ReadI2C2(); //Read the MSB data
IdleI2C2();
transpc('2');
NotAckI2C2() ;
IdleI2C2();
lsb = ReadI2C2(); //Read the LSB data
IdleI2C2();
StopI2C2();
deco(12,msb);vGLCDUpdate();
deco(23,lsb);vGLCDUpdate();
//printf("0x%02X ", msb);
//printf("0x%02X ", lsb);
//Test
msb = 0b11100111;
lsb = 0b00000000; //From the datasheet, -25C
deco(12,msb);vGLCDUpdate();
deco(23,lsb);vGLCDUpdate();
temp = (msb<<8) | lsb;
temp >>= 4; //The TMP102 temperature registers are left justified, correctly right justify them
//The tmp102 does twos compliment but has the negative bit in the wrong spot, so test for it and correct if needed
if(temp & (1<<11))
temp |= 0xF800; //Set bits 11 to 15 to 1s to get this reading into real twos compliment
//printf("%02d\n", temp);
//But if we want, we can convert this directly to a celsius temp reading
//temp *= 0.0625; //This is the same as a divide by 16
//temp >>= 4; //Which is really just a shift of 4 so it's much faster and doesn't require floating point
//Shifts may not work with signed ints (negative temperatures). Let's do a divide instead
temp /= 16;
return(temp);
}int16_t tmp102Read(void)
{
uint8_t msb, lsb;
int16_t temp;
i2cSendStart();
i2cWaitForComplete();
i2cSendByte(TMP_WR); //We want to write a value to the TMP
i2cWaitForComplete();
i2cSendByte(TEMP_REG); //Set pointer regster to temperature register (it's already there by default, but you never know)
i2cWaitForComplete();
i2cSendStart();
i2cSendByte(TMP_RD); // Read from this I2C address, R/*W Set
i2cWaitForComplete();
i2cReceiveByte(TRUE);
i2cWaitForComplete();
msb = i2cGetReceivedByte(); //Read the MSB data
i2cWaitForComplete();
i2cReceiveByte(FALSE);
i2cWaitForComplete();
lsb = i2cGetReceivedByte(); //Read the LSB data
i2cWaitForComplete();
i2cSendStop();
//printf("0x%02X ", msb);
//printf("0x%02X ", lsb);
//Test
//msb = 0b11100111;
//lsb = 0b00000000; //From the datasheet, -25C
temp = (msb<<8) | lsb;
temp >>= 4; //The TMP102 temperature registers are left justified, correctly right justify them
//The tmp102 does twos compliment but has the negative bit in the wrong spot, so test for it and correct if needed
if(temp & (1<<11))
temp |= 0xF800; //Set bits 11 to 15 to 1s to get this reading into real twos compliment
//printf("%02d\n", temp);
//But if we want, we can convert this directly to a celsius temp reading
//temp *= 0.0625; //This is the same as a divide by 16
//temp >>= 4; //Which is really just a shift of 4 so it's much faster and doesn't require floating point
//Shifts may not work with signed ints (negative temperatures). Let's do a divide instead
temp /= 16;
return(temp);
}
void ioinit(void)
{
//1 = output, 0 = input
DDRB = 0b11111111;
DDRC = 0b11111111;
DDRD = 0b11111111;
PORTC = 0b00110000; //pullups on the I2C bus
//Init Timer0 for delay_us
TCCR0B = (1<<CS01); //Set Prescaler to clk/8 : 1click = 0.5us(assume we are running at external 16MHz). CS01=1
//Setup USART baud rate
UBRR0H = SERIAL_MYUBRR >> 8;
UBRR0L = SERIAL_MYUBRR;
UCSR0B = (1<<RXEN0)|(1<<TXEN0); //No receive interrupt
UCSR0A &= ~(1<<U2X0); //This clears the double speed UART transmission that may be set by the Arduino bootloader
stdout = &mystdout; //Required for printf init
}