This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Part Number: MSP432P401R
I am unable to get temperature readings from the TMP100. I am using EUSCI B2. In tracing my code ( using as much of the Driverlin APIs as possible).
ADD0 AND ADD1 lines are grounded on the chip
I have included a screen shot of the SCL and SDA waveforms when i call: TMP100SendData( data_buffer, SlaveAddress);
in the TMP100Init(...) fucntion the function and execute the line:
MAP_I2C_masterSendMultiByteStart(EUSCI_B2_BASE, buffer[i]); // Send start, address and 1st byte
It appears the code is writing the correct address ( i.e. 0x48, but i see no 'ACK' before sending 0x01 )
SCL - Top plot
SDA - Bottom plot
CODE:
#define TMP100_SLAVE_ADDRESS0 0x48
#define TMP100_RES_12BITS 0x60 // Typically 320ms conversion time
#define NON_SHUTDOWN_MODE 0x00 // Continuous conversion
After setting up the EUSCI_B2 as a Master, I run the following initailization function:
TMP100Init(TMP100_SLAVE_ADDRESS0, TMP100_RES_12BITS | NON_SHUTDOWN_MODE ); // Equiv to TMP100Init( 0x48, TMP100_RES_12BITS | NON_SHUTDOWN_MODE )
void TMP100Init(uint_fast16_t SlaveAddress, uint8_t Config_Reg_Value )
{
uint8_t data_buffer[3];
data_buffer[0] = TMP100_CONFIG_REGISTER; // 0x01
data_buffer[1] = Config_Reg_Value ; // 0x01
data_buffer[2] = 0; // Buffer termination for 'TMP100SendData routine
TMP100SendData( data_buffer, SlaveAddress);
// Reset to reading Temperature
data_buffer[0] = TMP100_TEMP_REGISTER;
data_buffer[1] = 0; // Buffer termination for 'TMP100SendData routine
TMP100SendData( data_buffer, SlaveAddress);
}
void TMP100SendData( uint8_t *buffer, uint_fast16_t SlaveAddress)
{
unsigned int i = 0;
// Specify slave address
MAP_I2C_setSlaveAddress(EUSCI_B2_BASE, SlaveAddress);
// Set Master to transmit mode
MAP_I2C_setMode(EUSCI_B2_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
MAP_I2C_masterSendMultiByteStart(EUSCI_B2_BASE, buffer[i]); // Send start, address and 1st byte
i++;
while( buffer[i] != 0)
{
MAP_I2C_masterSendMultiByteNext(EUSCI_B2_BASE, buffer[i]);
i++;
}
MAP_I2C_masterSendMultiByteStop(EUSCI_B2_BASE); // End Transmission
}
David,
My suggestion below for using a known-working program to read I2C assumes that you are working from a LaunchPad. If this is not correctly, the below may not work for you. If that's the case let me know and we can try something else.
First I might try running one of the TI Driver (uses a TI-RTOS) example that's known to exercise the I2C to read a temperature. The "i2ctmp007" example under TI Resource Explorer / Software / SimpleLink reads an I2C temperature sensor (TMP007) from the TI Sensor Hub boosterpack. It uses a different EUSCI instance and I2C address (the latter you can change by editing the variable TMP007_OBJ_TEMP in the i2ctmp007.c source file).
This program simply reads the temperature and outputs the values to the backchannel UART.
This should at least allow you to see if the hardware or software is at fault. (Though it's suspicious that you are not getting an ACK, which suggests a connection problem or perhaps addressing issues.) Running the above program at least gives you a known-working starting point.
FOR MORE INFORMATION, see the SimpleLink Academy "Multi-threaded RTOS Thermostat" module to learn how to use the Sensor Hub boosterpack and read temperatures via I2C.
Regards,
Bob
Hello David,
We have some i2c drivers (using driverlib) that you may find very useful part of boostxl_sensors_sensorgui example.
Please look into tmp007.c and i2c_driver.c. It should be very simple to port it over to support the TMP100, could you please give this a try and let us know if you see the same behavior.
Hopefully this helps.
David
Hi Bob,
I changed my SCL and SDA pullup resistors and the TMP100 initialization works.
My next problem is reading the temperature data using driverlib APIs.
I had a look at non-rtos examples (tmp006 code for the educational booster mkii, and the simplelink drivelib example 'i2c_master_rw_repeated_start-master_code.c')
I tried 2 code implementations: (Added lines numbers for clarity)
Code 1 is lines 1-12 and does not work.
This hungs up the 2nd time i execute on line 3. I have noticed that
SDA is low on the 2nd run. The only way i can get around this is to power cycle the TMP100 IC.
Code 2 is just lines 1, 4-12. (i.e lines 2 and 3 are not included).
This sort off works however when i use 2 TMP100 devices with different addresses,
when the code is run targeting one TMP100 , it reports the temperature of the other device. It seems the
values in lines 5 and 7 are from the previously read TMP100.
Note: I perform the following:
Read_Sensor1->Read_Sensor2->Read_Sensor1.....etc
Where Read_SensorX runs the code for the specified TMP100.
The lines 6 and 7 are in that order due to a comment in the 'i2c_master_rw_repeated_start-master_code.c' code which uses that order.
This is the comment:
/*
* Switch order so that stop is being set during reception of last
* byte read byte so that next byte can be read.
*/
Actually when i switch lines 6 and 7, the temperature reading does not change even when i heat or cool the TMP100
Code :
float TMP100ReadTemperature( uint_fast16_t SlaveAddress)
{
volatile uint16_t temp = 0;
volatile uint16_t val = 0;
volatile uint16_t valscratch = 0;
float tempval;
1. MAP_I2C_setSlaveAddress(EUSCI_B2_BASE, SlaveAddress);
2. MAP_I2C_setMode(EUSCI_B2_BASE,EUSCI_B_I2C_TRANSMIT_MODE);
/* Send start and the first byte of the transmit buffer. */
3. MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, 0x00]); // Point to Temperature register
4. MAP_I2C_masterReceiveStart(EUSCI_B2_BASE);
5. val = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B2_BASE);// Get MSByte
6. MAP_I2C_masterReceiveMultiByteStop(EUSCI_B2_BASE);// Send STOP
7. valscratch = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B2_BASE);// Get LSByte
8. val = (val << 8) & 0xFF00; // Shift to top MSB
9. valscratch = valscratch & (0x00FF);
10. temp = val | valscratch;
11. temp = temp >> 4;
12. tempval = (float)temp* 0.0625;
}
Hi David,
Looks like you replied when i was posting my problem with reading temperatures. I will look at the tmp007 driverlib example. Thanks
David
I have tried to use some of the concepts employed in his post link (tmp007 with interrupt mode) with my tmp100 (non- interrupt mode) and run into problems indicated in my September 14, 2017 post. The 'i2c_driver.c' code performs some of the i2C status checks (e.g NAK, START, STOP) and i would like to know how i can implement similar checks in my non-interrupt mode of operation.
**Attention** This is a public forum