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.

MSP430FR5994: Problems reading consistent values from pins

Part Number: MSP430FR5994

I have a simple multiplex set up on a breadboard with 6 switches and 2 transistors (2x3). When one transistor is turned on, I read the pin values from the first half of the sensors, then I turn it off and turn on the other transistor and read the second set of sensors. My problem, I think, has to do with my code. If I step through the debugger (or comment out the 'check_key' function) everything works as it should, but if I let it run then incorrect values are displayed through the serial port.

Here are the results if I step through the debugger or if I comment out the 'check_key' code. The first value is the transistor (0 or 1) and the second number is the register value from P3.  It shows correctly with a value of '14',  which meant that when transistor #2 (1) was turned on, it read that switch #3 on that transistor read a value of 4.

12:17:06.212 -> 14
12:17:06.212 -> 14
12:17:06.212 -> 14

Here are the results when the code is ran:
09:41:08.195 -> 14
09:41:08.195 -> 14
09:41:08.195 -> 17
09:41:08.195 -> 17
09:41:08.195 -> 17
09:41:08.195 -> 17
09:41:08.195 -> 17
09:41:08.195 -> 14
09:41:08.195 -> 17
09:41:08.195 -> 07

In summary, it shows the correct value a few times, but then it starts reading very erratic numbers. For instance, a '7' would mean that all three sensors on the transistor were turned on. I also get random readings that shows transistor #1 (0) had all 3 sensors turned on (07).

Below is the relevant code:

#include <msp430fr5994.h>

typedef int bool;
#define TRUE  1
#define FALSE 0

char left_hand_output[] = { BIT2, BIT3 };
volatile unsigned int LeftKeysStatus[] = {
  0x00,
  0x00
};

char left_hand_input[] = { BIT0, BIT1, BIT2 };

unsigned int reg_values = 0;

void SerialPrint(char * tx_data, bool lineReturn);            // Outputs string to serial port
void UARTInit_Send(void);
char* Int_to_String(int i, char b[]);
void check_key(int reg, int group, bool on, bool left);

int main(void) {
    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

    UARTInit_Send();

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;

    P1DIR |= BIT2;// | BIT3; //Set P1.2 and P1.3 as output
    P1DIR |= BIT3;
    P1OUT &= ~BIT2;// | ~BIT3; //Turn off P1.2 and P1.3 initially
    P1OUT &= ~BIT3;

    P3DIR &= ~BIT0; // | ~BIT1 | ~BIT2; //Set P3.1, P3.2, P3.3 as INPUT
    P3DIR &= ~BIT1;
    P3DIR &= ~BIT2;
    P3REN |=  BIT0 | BIT1 | BIT2; //Enable pullup/down resistors
    P3OUT &=  ~BIT0 | ~BIT1 | ~BIT2; //Select pullup resistors

    while(1)                          // polling
    {
        volatile unsigned int i;
        for (i=0; i<2;++i){
            unsigned int pin = left_hand_output[i];
            P1OUT |= pin;
            //A slight delay is needed here or else we'll be reading the previous pin
            __delay_cycles(300);

            reg_values = P3IN;

            P1OUT &= ~pin;

            //check if something changed
            if (reg_values != LeftKeysStatus[i]){

                //-----------THIS READS THE CORRECT VALUE--------------
                //char indexValue[12];
                //Int_to_String(i, indexValue);
                //SerialPrint(indexValue, FALSE);
                //char dataValue[12];
                //Int_to_String(reg_values, dataValue);
                //SerialPrint(dataValue, TRUE);


                //if the byte value is greater, we're turning the switch on; else, turning it off.
                if (reg_values > LeftKeysStatus[i]){
                    //using bit-wise OR to send modified bits only
                    check_key(reg_values ^ LeftKeysStatus[i], i, TRUE);
                }
                else {
                    check_key(reg_values ^ LeftKeysStatus[i], i, FALSE);
                }
            }
        }
    }
}

//Check to see which bits have changed and send the appropriate midi message
void check_key(int reg, int group, bool on){
    //-----------THIS READS THE WRONG VALUE--------------
                    char indexValue[12];
                    Int_to_String(group, indexValue);
                    SerialPrint(indexValue, FALSE);
                    char dataValue[12];
                    Int_to_String(reg, dataValue);
                    SerialPrint(dataValue, TRUE);
}

Any help on what is going on would be appreciated.

  •  P3OUT &=  ~BIT0 | ~BIT1 | ~BIT2; //Select pullup resistors

    This statement has no effect. I suspect you meant:

     P3OUT &=  ~(BIT0 | BIT1 | BIT2); //Select pulldown resistors

    I'm not sure this is causing your symptom, but it's probably getting in the way of your experiment.

    The REN resistors are fairly high impedance (20-30k). What is the source impedance of your sensors? (I'm wondering if you're voltage-dividing into the gap between low and high.)

  • Thanks Bruce, I updated that portion of the code, but as you assumed, it did not change the results. The transistors are PN2222A. They are connected to the ground, which are then in turn connected to the sensors. The sensors are TI hall sensors: https://www.ti.com/product/DRV5011. They are connected to the 5V in. Operating conditions are 2-5 - 5V.

  • OUT gets driven at Vcc, so power them from a 3V3 pin. Powering with 5V can fry the input pin.

    [Edit: I forgot the reference: Data Sheet (SLVSCY6B) Sec 5, Table "Pin Functions".]

**Attention** This is a public forum