First time on the forum so I hope I am doing this correctly?
I have a simple Arduin program that sends two sensor readings to the Android via blutooth and also the Android can send back commands.
My Inventor blocks are below. The problem is the two sensor readings are not appearing separately as they should. Receved_data2 shows both readings and the comma (') separator.
I do not understand your Script - 'Serial1' appears to be listening for data from the App yet it is also printing.
Questions
Why do you have three delays inside the loop? When you trigger a delay, everything is paused - you would normally control the frequency/duration of the loop by comparing current millis with elapsed millis.
Am I right to assume that Serial.println (buffer) is how you are sending to the App?
If so, change the code thus:
void setup()
{
Serial.begin(9600);
igUpdateTime = millis();
}
void loop()
{
//Excute Serial Comms every 2 seconds
if(millis() - igUpdateTime > 2000)
{
igUpdateTime = millis();
if (Serial.connected())
{
//Data to App via Bluetooth
Serial.print("Hello");
Serial.print("|");
Serial.print("World");
Serial.print("|");
Serial.println();
//This last line tells App "End of Data"
// = Ascii LineFeed Char Number 10
//If the App uses Bluetooth Classic,
//set the Bluetooth Client Delimiter
//Block to 10 (math 10, not text 10)
}
}
}
.... I see you are using a comma as the value separator, which is fine, but a better habit is to use a bar, as this is less likely to be included within string data .
Note
Can't see all your App code but can see an error - the "Bytes Available" flag is just that - a flag to signify there is data to read. To read all of the data, the bytes to read should be -1.
Also in the App code:
(a) The App needs to know what the End-Of-Data flag is.
(b) the Clock Timer for data read should be approx 20% faster than the Sketch Loop.
I attach a Classic BT template Project which has been successfully used by many App Inventor Users.
The delays were just me being lazy to create a flash. Millis option understood and clearly better when dealing with Serial. Delays removed now.
Yes the buffer is just used to send the serial. Is there a problem with using a buffer?
The comms via serial1 is two way. Vales from Arduino to Android and comands from Android to Arduino.
Whether I send the buffer or just individual serial.prints the result is the same. What I dont understand is why receved_data2.txt shows both values ?
One clue might be the first block receives the first value correctly and the second gets the 2nd value first, followed by the second. Is this because I need to send an end of line marker as well?
I have tried to understand your emails but am getting stuck at defining the end of line in the blocks (at least I think that is the issue) as the second text box shows both first and second values together but in reverse order while first text field just shows first value.
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.
That means the delimiter used by the Sketch is not the same as the delimiter used by the App.
In the App, the data Should be Split at a bar "|" as that is the delimiter used in the Sketch.
I clearly have some reading to do on end markers. Appreciate the pointer AG and as I a sending multiple data (from your comment below), I thought (from my blocks image) I was splitting a variable and checking list length etc? Am I missing something?
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.
Also I did check my separator was the same and it was in the APP.
I have changed the code to read the below to remove the last delay which has improved the APP in that both text boxes now have the right number - most of the time, so it must be my end marker now?
int state;
int val = 218;
int val1 = 249;
unsigned int igUpdateTime;
Thanks ABG. More of a didnt quite understand than an ignore. I will read up on it now.....
I have the blocks now as suggested and the clock timer set to 1/2 of the transmission speed but the APP wont display the values now and halts (not responding)
I've noticed that changing the send rate Vs the clock speed makes it crash which is understandable i guess. It seems stable-ish at 500ms clock and 1000ms send rate.....BUT the data fields just don't update at all (no values displayed) and I would like then to update once a second ideally.
The power on/off part of the code from android back to arduino works well it is just the values receive to the APP.
In my blocks I check for list length. It will always be 2 items so when looking for item 1 is list length >= 1 correct?
Use a separate global variable for the result of the split operation,
to not muddy your input. Use the Do It operation to see contents before and after the split.
Add an extra Label to your app to show the BytesAvailable backlog in the Clock Timer,
to let you know if your connection is constipated. If it grows without stop, you are drinking from a firehose.
Thanks ABG. Function has changed a little. the first value field updates but only when I send the 'power up' command. The 2nd value field just says 'error' now.
Sorry to be so needy. I am reading as much as I can. I know once I get this basic APP working it will really help the understanding.
Delimeter set to 10
New data variable set.
I couldn't find a reference to the DO IT operation?
and I am not sure what bytes available function to use to show the backlog?