First time and trouble with multiple sensor program

....Example of how to receive data from the App:

//vars
unsigned int igUpdateTime;
char val[];

void setup()
{
         Serial.begin(9600);
         igUpdateTime = millis();
}

void loop()
{
         //Excute loop every 1/2 second
	     if(millis() - igUpdateTime > 500) 
         {
              igUpdateTime = millis();

              if (Serial.available() > 0)
              {
                   //Read Data From App
                   val = Serial.read();

                   switch (val) {

                     case '1':
                              digitalWrite(led1, HIGH);
                              break;

                     case '2':
                              digitalWrite(led1, LOW);
                              break;

                     case '3':
                              digitalWrite(led2, HIGH);
                              break;

                     case '4':
                              digitalWrite(led2, LOW);
                              break;
                   }
              }
         }
}

Chris

Thank you. To answer.....

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?

It could exceed the "MTU" (pay load) size of the data packet, so better to fire off tiny packets.

Yes.Plus the App needs to know what the marker is - that's all covered in my examples.

Chris

Sorry still a bit new to this clearly....

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.

So my blocks are

and my code is;
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
pinMode(3, OUTPUT);

}

int state;
int val = 217;
int val1 = 345;

void loop()
{

Serial1.print (val);
Serial1.print ("|");
Serial1.print (val1);
Serial.print("|");
Serial.println();
delay (500);

if (Serial1.available() > 0)
{
state = Serial1.read();
Serial.println (state, HEX);
}
if (state == '0')
{
digitalWrite(3, LOW);
}
if (state == '1')
{
digitalWrite(3, HIGH);
}

}

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.

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.

Also - typos here:

Serial1.print (val);
Serial1.print ("|");
Serial1.print (val1);
Serial.print("|");
Serial.println();
delay (500);

Should be:

Serial1.print (val);
Serial1.print ("|");
Serial1.print (val1);
Serial1.println();

Do not use delay()!
I have already given an example of how to use elapsed millis.

Thanks both.

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;

void setup() {
Serial.begin(9600);
Serial1.begin(9600);
pinMode(3, OUTPUT);
igUpdateTime = millis();
}

void loop()
{

if (millis() - igUpdateTime > 1000)
{
igUpdateTime = millis();

if (Serial1.available() > 0)
{
  Serial1.print (val);
  Serial1.print ("|");
  Serial1.print (val1);
  Serial.println();
}

}

if (Serial1.available() > 0)
{
state = Serial1.read();
Serial.println (state, HEX);
}
if (state == '0')
{
digitalWrite(3, LOW);
}
if (state == '1')
{
digitalWrite(3, HIGH);
}
}

If you want us to check your blocks and Delimiter attribute,


Please export your project and post it here.

Thank you very much. File attached.

LedControlWithBluetooth_5_listsplit_copy.aia (12.0 KB)

Kev

You ignored the part about setting the Delimiter byte to 10 and asking for -1 bytes.
BlueToothClient1
These replacement blocks can be dragged into the Blocks Editor to fix that.

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)

LedControlWithBluetooth_11_listsplit_copy_copy.aia (12.2 KB)

Sorry, I need some more help please.......

My blocks and code are set as in the last post.

My two text received fields are still 'stuck'.

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?

Suggestions:
Capture

  • Set the Delimiter Byte to 10 in the Designer

  • 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?

Updates file attached.
LedControlWithBluetooth_13_listsplit_.aia (12.2 KB)

Here is a log facility I recommend to capture your message stream and timestamp it.
You will need to add a List Picker to display the log.

Clicked on log logger_to_list.aia (2.6 KB) sample run when btnEnter Click

Call the log() function with your global variable that caught the incoming message at the top of the Clock Timer.

Here's an update .aia file ...
LedControlWithBluetooth_13_ABG.aia (13.4 KB)

Brilliant. Thanks. I will play with that. BTW I have made some progress......dumb error ...my Serial.println(); should have been Serial1.println(); Explains why the end marker wasn't happening!!! Late nights!

I am just running the prints in the loop and it seems to receive the values pretty well.

val = random (20);
val1 = random (100,105);
Serial1.print (val);
Serial1.print ("|");
Serial1.print (val1);
Serial1.println();

Thanks for reporting the error.
They are too good to waste.
Maybe we should start recommending people name their Arduino components as well as their AI2 components, to ease debugging.

Hmm, I pointed that out to you about 100 years ago :joy: