Hello I’m trying to design an app that can get information from an MSP432 via Bluetooth. So far I receive information but the app just keeps printing the information that it first received and nothing afterwards. I believe it is a problem on the app side since I have debugged my MSP code and it seems like the right values are being sent through the UART transmitter. Thank you for your help.
Hello Juan
Need to see your App Blocks for bluetooth (BLE) and your MSP code - they have to work in unison. Capture an image of the Blocks via App Inventor’s right-mouse menu.
This is the code I’m using
#include “msp.h”
int x;
int EMG;
int y;
int z;
uint8_t tx_buffer[3];
uint16_t bufferIndex = 0;
void main(void){
WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer
P3->SEL0 |= BIT2 | BIT3; //set p3.2 and p3.3 as UCA2RXD & UCA2TXD
P5->SEL1 |= BIT5 | BIT4 | BIT2 | BIT1; //| BIT4 | BIT3; //Set p5.5 as ADC input A0 and p5.4 ad ADC input A1 and p5.2 as channel A3 5.1 channel a4
P5->SEL0 |= BIT5 | BIT4 | BIT2 | BIT1; //| BIT4 | BIT3; //Set p5.5 as ADC input A0 and p5.4 ad ADC input A1 and p5.3 as channel A2
//lcdInit();
//lcdClear();
//set up ADC clock
CS->KEY = CS_KEY_VAL;
CS->CTL1 |=CS_CTL1_SELA_2;
CS->KEY = 0;
//Configure SMCLK as 12MHz from DCO
CS->KEY = CS_KEY_VAL;
CS->CTL0 &= ~CS_CTL0_DCORSEL_MASK;
CS->CTL0 |= CS_CTL0_DCORSEL_3;
CS->CTL1 |= CS_CTL1_SELS_3;
CS->KEY = 0;
EUSCI_A2->CTLW0 |= EUSCI_A_CTLW0_SWRST; //Hold eUSCI module in reset
EUSCI_A2->CTLW0 |= EUSCI_A_CTLW0_UCSSEL_2; //Select SMCLK as EUSCI_2 clock
//Set Baud Rate to 9600 from Table
EUSCI_A2 -> BRW = 78;
EUSCI_A2->MCTLW = 0x0020 | EUSCI_A_MCTLW_OS16;
EUSCI_A2->CTLW0 &= ~ EUSCI_A_CTLW0_SWRST; //Clear SWRST to resume operation
ADC14->CTL0 &= ~ADC14_CTL0_ENC; //reset ENC bit for configuration
ADC14->CTL0 = ADC14_CTL0_SHS_0 | ADC14_CTL0_SHP | ADC14_CTL0_CONSEQ_3 | ADC14_CTL0_SHT0_7 | ADC14_CTL0_MSC | ADC14_CTL0_ON;
//Timer_A0 output 1 trigger, Sampling timer is the source of sampling signal, multi channel-repeated conversion mode, sample-n-hold time is 96 ADC clock cycles, ADC14 on.
ADC14->CTL1 = ADC14_CTL1_RES_3;
ADC14->MCTL[0] = ADC14_MCTLN_VRSEL_0 | ADC14_MCTLN_INCH_0;
ADC14->MCTL[1] = ADC14_MCTLN_VRSEL_0 | ADC14_MCTLN_INCH_1;
ADC14->MCTL[3] = ADC14_MCTLN_VRSEL_0 | ADC14_MCTLN_INCH_3 | ADC14_MCTLN_EOS;
// ADC14->MCTL[4] = ADC14_MCTLN_VRSEL_0 | ADC14_MCTLN_INCH_4 | ADC14_MCTLN_EOS;
ADC14->IER0 = ADC14_IER0_IE3; //Enable interrupt once MEM[4] is filled, should be after the fourth channel's conversion
ADC14->CTL0 |= ADC14_CTL0_ENC | ADC14_CTL0_SC; //Start conversion
NVIC->ISER[1] = 0x00040000; //EUSCI_A2 interrupt is enabled in NVIC
NVIC->ISER[0] = 0x01000000; //ADC14 interrupt is enabled in NVIC
__enable_irq(); //All interrupts are enabled
SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; //Sleep on exit
__sleep(); //enter LPM0
}
void ADC14_IRQHandler(void){
if (ADC14->IFGR0 & ADC14_IFGR0_IFG0){
x = ADC14->MEM[0]; //p5.5
y = ADC14->MEM[1]; //p5.4
z = ADC14->MEM[3]; //p5.2
tx_buffer[0]=(x/64);
tx_buffer[1]=(y/64);
tx_buffer[2]=(z/64);
if (EUSCI_A2->IFG & EUSCI_A_IFG_TXIFG){
if(bufferIndex<3){
EUSCI_A2->TXBUF = tx_buffer[bufferIndex++];
}
else{
bufferIndex=0;
EUSCI_A2->IE &= ~EUSCI_A_IE_TXIE;
}
}
}
}
void EUSCIA2_IRQHandler(void){
EUSCI_A2->IE &= ~EUSCI_A_IE_TXIE;
}*
Right
-
I’m surprised your App receives a value, doesn’t the MSP432 use BLE? (Bluetooth Low Energy). If I’m correct, then you must use the App Inventor BLE extension:
https://www.professorcad.co.uk/appinventortips#TipsBluetooth (BLE link on this page) -
I can’t see in your Script how the values you wish to send, are sent:
(2a) There is no loop in the code, meaning that data is only sent once - is that intentional?
(2b) When the App first receives the data, is that three values at the same time? We need to tell the App when the data send is complete.
(2c) If the values are sent together, or within quick succession, a delimiter character such as a bar char (|) must be used.
(2d) We need to ensure that the data send time interval is slower than the data receive time interval, to avoid a freeze or crash. I suggest using large time intervals initially, say 1000 milliseconds @ MSP432 and 800 milliseconds @ the App -and always use the largest intervals appropriate to the task. If that’s measured in minutes or hours, so much the better.
By the way, ensure the MSP432 is kept cool!
Juan, I’m in the UK and closing down now. I’ll keep an eye out for your posts tomorrow.
- Sorry I forgot to mention the MSP is hooked up to an HC-05 to send the information. I tried using BLE but the phones I am testing the app on do not work with BLE.
2a) The ADC interrupt is triggered every time there is a value to written into the ADC memory, and since it is running in continuous mode this happens all the time. I have checked and when I move my accelerometer the new values of the ADC are loaded into the TX buffer.
2b) When the app first receives data it does take in all the values at the same time and stores each one into a different list. This is done because I want to create an excel file that I can then import into my computer.(this part of the app works)
2c) I tried to use the split text block with a “|” as a way to separate the variables but it did not seem to work. Maybe it is because I am sending integers?
2d) Currently the Bluetooth Timer on my app is set to 500ms I can try to include a delay in my MSP code but I was trying to avoid as I am trying to receive ADC values in real time.
Hi
In your Blocks, you have 3 BT calls in succession - if that has worked before, it’s a miracle It should be one call collecting all 3 values.
Your Script needs to seperate the values (|) and notify the end of data stream (\n). For the purposes of your App, it doesn’t matter if the numbers arrive as strings (text). Note that the App must know the end of data char:
You cannot achieve “real time” data collection but you can tweak-down from something that works reliably until you find your limit, which will be close. If the concern for real time data is to not lose any potentially valuable data, do the house keeping after all data collection is finished - so pour the data as-is into a string*, then parse that at the end of your data collection session. Experiment first, it may be that nothing ever changes significantly that can’t be captured in the space of one or two second intervals. Others have discovered that their data produced the same result whether using a 1 second interval or a 1 minute interval - the aim should be to find the maximum interval that satisfies the data requirement as this yields reliability throughout the session.
*or append a file if data is very large
I used this example and I was able to split the values I was sending the only problem is that I my integers get converted to ASCII character and they just keep scrolling through the spots
Would the delimiter byte help split between data sets? Im not sure what it is for. I will try to add a delay and see how it works as well.
Would the delimiter byte help split between data sets?
Yes, each data set consists of 3 values:
val1|val2|val3\n
- I can't read the Blocks in your latest image
To get the best image of Blocks, use the right-click menu in App Inventor, "download blocks as image"
Did you disable your true/false blocks and your number value blocks?
They look suspiciously white, a recipe for disaster.
Here is standard Delimiter advice ...
Please see the Delimiter article in FAQ
Be sure to use println() at the end of each message to send from the Arduino, to signal end of message. Do not rely on timing for this, which is unreliable.
Also, return data is not immediately available after sending a request,
you have to start a Clock Timer repeating and watch for its arrival in the Clock Timer event. The repeat rate of the Clock Timer should be faster than the transmission rate in the Arduino, to not flood the AI2 buffers.
In your Clock Timer, you should check
Is the BlueTooth Client still Connected?
Is Bytes Available > 0?
IF Bytes Available > 0 THEN
set message var to BT.ReceiveText(-1)
This takes advantage of a special case in the ReceiveText block:
ReceiveText(numberOfBytes)
Receive text from the connected Bluetooth device. If numberOfBytes is less than 0, read until a delimiter byte value is received.
If you are sending multiple data values per message separated by | or comma, have your message split into a local or global variable for inspection before trying to select list items from it. Test if (length of list(split list result) >= expected list length) before doing any select list item operations, to avoid taking a long walk on a short pier. This bulletproofing is necessary in case your Arduino sneaks in some commentary messages with the data values.
Here are the blocks from the previous example, I also tried to add the blocks you suggested but I am not sure I have set them up right.
Hi Juan
With the corrections as shown by ABG, you have got the Blocks setup correctly, except for the timer. Note also that the comments about Serial Comms etc apply to a different microprocessor/script, not applicable to your setup.
The Clock Timer should not be started until the BT connection has been made.
It’s best to set the Timer up in the Screen Initialize Block. You should not require “Timer Always Fires”.
The global Var “COMMENT” is just a simple way to comment your code in-line, anywhere in any Block.
It seems to work now but everything I sent is received as an ASCII character is there a way for me to send an integer and actually receive a number value on the app?
Hi Juan
You sure they are ASCII and not UTF8? Shouldn’t matter though if only ever receiving integer characters.
Send text instead of integers.
The data is going into a file/text box/label -all of those handle the numbers as text. When you display the processed the data (in a graph for example), it can be read as numbers. In many cases, App Inventor recognises “text numbers” anyway.
When I display the data inside the Labels they show up as symbols instead of numbers is there a way to change that?
Hi Juan
It’s always helpful if you can show us your latest code. Anyway, is the Script now sending text instead of numbers? If it is:
- Text is UTF8 format? (or ASCII format? or something else?)
- Can we see the symbols in the Labels? (Use the Android Device screen snapshot facility)
I read a bit on the MSP432 on ti.com, and went back and reread the C code in prior posts in this thread.
I don’t see any place in the code where native int data types get converted to text strings before being sent, so any talk of delimiters is useless, since the int values could possibly match the int values of whatever text delimiter character (| or \n) you send.
I see in the TI software sdk download site they have free sample code (and IDEs) for sending JSON strings from the MSP432.
https://www.ti.com/lit/ug/slau597f/slau597f.pdf?ts=1588782953719
AI2 loves JSON, now that it has the new dict data type and the Web component blocks for JSON conversion.
I will look into that. I am running the same app with an Arduino and using print() everything seems to be running smoothly.