I'm working on a project that is taking in two types of data via the serial of an Arduino that is plugged into my phone. They will be strings with a "P" or "T" as the first character in the string, and the rest of the string will be numbers that represent either a pulse rate or temperature. How to I set up a code block that detects what the first letter is in the string and saves the numbers after the letter in the appropriate variable?
You have to use Line Feed delimiters to get full messages.
Standard advice for that will be at the bottom of this post.
When a message arrives, save it into a global Message variable for further reference.
Since there will be at most one letter in the message, you can use the text CONTAINS block on each option
if contains(Message,'T') then
replace 'T' in Message with empty text block
treat Message as a number with temperature
else if contains(Message,'P') then
replace 'P' in Message with empty text block
treat Message as a number with pressure
else complain about bad message
Delimiter advice:
Please see the Delimiter article in FAQ
Be sure to use println() at the end of each message to send from the sending device, to signal end of message. Do not rely on timing for this, which is unreliable.
In the AI2 Designer, set the Delimiter attribute of the BlueTooth Client component to 10 to recognize the End of Line character.
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 sending device, 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 sending device sneaks in some commentary messages with the data values.
Hello bmeguy welcome to the forum
What you are doing there should be completely unnecessary, can we see your Sketch (.ino) file?
Hi there. I'm not quite sure how to export my project as a .ino file. I only seem to see options for exporting as an .aia or a .apk, or a .abb file.
Ask the person who is coding on the Arduino.
Ah, I thought the person above was referring to the file for the app innovator. Here is the .ino file.
finalsensortest.ino (14.2 KB)
The code in the .ino seems to be adapted from a different project (it's very messy!). There's a lot that perhaps should not be there yet the two values you wish to receive in the App, 'tempAve' and 'pulseAve' (?) are not actually collected and calculated within the loop before being sent. Also, it is not necessary to use (C++) 'String'. Once the code to populate the values is there, this is how to send them to the App (Note ABG's Advice):
Serial.print(tempAve);
Serial.print("|"); //Value delimiter
Serial.print(pulseAve);
Serial.println(); //This empty last line tells App "End of Data" = Ascii LineFeed Char Number 10
I think you may be intending to send other values too? Given that they should be sent in order by the Arduino, none of them require a prefix letter. Note that it is bad practice to assign variable types within the loop.
This is an example App Inventor Project that receives two values. Note, depending on your Android Version, Android permissions may be required.
BT_Basic_Setup_Receive_two_vals.aia (7.8 KB)
Yeah, the code is adopted from another project for someone who displayed the temp and pulse values on an LCD display.
The tempave and pulseave are the only outputs I care about. They are not calculated in the main loop that prints them. I made them global variables that are updated with each temp/pulse read and zeroed out after printing to the serial.
That's OK, but the procedure that does the calculation has to be called from within the loop.