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.

MSP432P401R: I2C how to add an analog pressure sensor's reading on a I2C bus

Part Number: MSP432P401R

I'm working on a new project with the TI MSP432P401R microcontroller. I'm reading from an analog pressure sensor (that is not connected to the I2C, the direct voltage reading goes to the MCU via ADC and then I do certain voltage-pressure conversion formulas to display the pressure on a TLT LCD screen). I have 2 I2C buses: I2C bus 1 is connected to a DAC in order to have a 0-10V or 4-20 mA output (only one output can be configured and thus only one DAC can be used, which DAC/output to use is chosen based on a switch). I2C bus 2 is connected to a smart port, where another device can be plugged in to get the data from my MCU. For this I implemented 2 different eUSCI modules: 1 eUSCI master module (from MCU(act as master) to DAC(act as slave)) and 1 eUSCI slave module (from MCU(act as slave) to smart port(act as master)). However, I'm stuck on how I am going to put the data read from the pressure sensor on the I2C bus, since my pressure sensor is analog and is not on the I2C bus, more precisely, I'm stuck on the transmission code. Here is my progress so far: (mostly I2C parts added as there are also ADC/timer configurations in between) I'm using TI's driverlib library. Here is some code:

/* Some variables */
const uint8_t TXData1[2] = {0x04, 0x00};
static uint8_t RXData1[NUM_OF_REC_BYTES];
static volatile uint32_t xferIndex1;
static volatile bool stopSent;

/* Some other application Variables */
static volatile uint8_t RXData2[NUM_OF_RX_BYTES];
static volatile uint32_t xferIndex2;
const uint32_t TXData2[NUM_OF_TX_BYTES + 1] =
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x10 };

int main(){

WDT_A_holdTimer();

/* Select Port 1 for I2C - Set Pin 6, 7 to output Primary Module Function,
* (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
*/
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P6,
GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE);
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1,
GPIO_PIN6 + GPIO_PIN7, GPIO_SECONDARY_MODULE_FUNCTION);

stopSent = false;
memset(RXData, 0x00, NUM_OF_REC_BYTES); //copies 0x00 to the first NUM_OF_REC_BYTES characters to the string RXData
xferIndex = 0;

/* eUSCI initializing I2C Master (for MCU to DAC) to SMCLK at 100khz with no autostop */
MAP_I2C_initMaster(EUSCI_B0_BASE, &i2cConfig);
//Specifying the slave address (we choose which DAC to use as a slave based on a switch)
if(GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN4)) MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS_DAC_V);
else
MAP_I2C_setSlaveAddress(EUSCI_B0_BASE,SLAVE_ADDRESS_DAC_mA);

/* Set Master in transmit mode */
MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
/* Enable I2C Module to start operations */
MAP_I2C_enableModule(EUSCI_B0_BASE);
/* Enable and clear the interrupt flag */
MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0);
//Enable master Receive interrupt
MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

/* eUSCI I2C Slave Configuration (for MCU to SmartPort) */
MAP_I2C_initSlave(EUSCI_B1_BASE, SLAVE_ADDRESS_MCU, EUSCI_B_I2C_OWN_ADDRESS_OFFSET0,
EUSCI_B_I2C_OWN_ADDRESS_ENABLE);

/* Enable the module and enable interrupts */
MAP_I2C_enableModule(EUSCI_B1_BASE);
MAP_I2C_clearInterruptFlag(EUSCI_B1_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT1);
MAP_I2C_enableInterrupt(EUSCI_B1_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT1);

MAP_Interrupt_enableSleepOnIsrExit();
MAP_Interrupt_enableMaster();
MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
MAP_Interrupt_enableInterrupt(INT_EUSCIB1);
MAP_Interrupt_enableInterrupt(INT_TA0_N);

while (1) MAP_PCM_gotoLPM0();

}

The configuration is like this so far. I'd appreciate any help about how I am going to transmit from MCU to DAC and from MCU to smart port via I2C buses. Also please do let me know if there are any unclarities about the code or anything that looks totally wrong, as I am new to the I2C programming concept.
Thank you very much in advance and have a great day.

  • If you have not already, then please check out the example here.

    Regards,

    Chris

  • Part Number: MSP432P401R

    I'm working on a project with the TI MSP432P401R microcontroller. I'm reading from an analog pressure sensor (that is not connected to the I2C, the direct voltage reading goes to the MCU via ADC and then I do certain voltage-pressure conversion formulas to display the pressure on a TLT LCD screen). I have 2 I2C buses: I2C bus 1 is connected to a DAC in order to have a 0-10V or 4-20 mA output (only one output can be configured and thus only one DAC can be used, which DAC/output to use is chosen based on a switch). I2C bus 2 is connected to a smart port, where another device can be plugged in to get the data from my MCU. For this I implemented 2 different eUSCI modules: 1 eUSCI master module (from MCU(act as master) to DAC(act as slave)) and 1 eUSCI slave module (from MCU(act as slave) to smart port(act as master)). However, I'm stuck on how I am going to put the data read from the pressure sensor on the I2C bus, since my pressure sensor is analog and is not on the I2C bus. In summary, I have 2 eUSCI modules: 1 master and 1 slave. In master module, MCU sends the pressure reading in voltage form to DAC and in the slave module, MCU sends the pressure reading in voltage form to smart port where smart port is the master. Now my question is this: the reading I get from the pressure sensor is not connected directly to the i2c bus, it's connected to one of the ADC conversion pins on my MCU. How can I read from this pin and put that reading in my RX/TX buffers on my I2C buses?

    I tried writing a function like this for both eUSCI modules but it doesn't work unfortunately.

    void I2C_write16 (unsigned char pointer, unsigned int writeByte) //pointer is the register address to modify and writeByte is my pressure reading in voltage form that I want to put on my I2C buses
    {
    /* Set master to transmit mode PL */
    I2C_setMode(EUSCI_B0_BASE,
    EUSCI_B_I2C_TRANSMIT_MODE);

    /* Clear any existing interrupt flag PL */
    I2C_clearInterruptFlag(EUSCI_B0_BASE,
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

    /* Wait until ready to write PL */
    while (I2C_isBusBusy(EUSCI_B0_BASE));

    /* Initiate start and send first character */
    I2C_masterSendMultiByteStart(EUSCI_B0_BASE,
    (unsigned char)( ((writeByte>>8) & 0x0F) | ((pointer << 4) & 0x30) ) );


    I2C_masterSendMultiByteFinish(EUSCI_B0_BASE,
    (unsigned char)(writeByte & 0xFF));

    }

    Thank you in advance and have a great day.

  • Thank you for reposting. 

    Let's focus on 1 I2C bus at a time.  First, please ensure pullup resistors are on the SDA and SCL communication lines.  Second, can you take a basic I2C example and modify for your communication with the DAC?

    Please make sure that the configuration matches the requirements of the DAC:

    /* Slave Address for I2C Slave */
    #define SLAVE_ADDRESS 0x48
    
    /* Statics */
    static uint8_t TXData = 0;
    static uint8_t TXByteCtr;
    
    //![Simple I2C Config]
    /* I2C Master Configuration Parameter */
    const eUSCI_I2C_MasterConfig i2cConfig =
    {
            EUSCI_B_I2C_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
            3000000,                                // SMCLK = 3MHz
            EUSCI_B_I2C_SET_DATA_RATE_400KBPS,      // Desired I2C Clock of 400khz
            0,                                      // No byte counter threshold
            EUSCI_B_I2C_NO_AUTO_STOP                // No Autostop
    };

    Please confirm that you can see the communication on the I2C pins (scope or logic analyzer).  

    Once this communication is working properly move to the other bus which will serve as the slave.  Here is another example of the slave.  Please note that no configuration is needed as the device will use and respond to the master clock.  Depending upon the communication used, you may not need to write first and then read (from the perspective of the master) and you can simply have the slave device update the transmit buffer.

    Regards,

    Chris

  • Hello,

    Thank you for your response. I just don't get how I'm going to put my pressure variable on the I2C bus. The variable is of type 'float'. I don't think I can simply do 

    pressure = TXData and then do MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData++). Thank you very much for the examples provided I've checked them over and over but I can't seem to set my pressure variable equal to TXData and then do the masterSendMultiByteStart/Next/Stop to transfer it over the I2C bus.

    Regards,

    Ege

  • The I2C peripheral transmits information in bytes, so you will need to simply send the four bytes and then concatenate the information at the master to create the float, see example.

    Regards,

    Chris

**Attention** This is a public forum