Strange problem reading serial via Bluetooth

My current project is controlling three LEDs via Bluetooth with an Android app I wrote for that purpose. The app has three sliders to control the three different colors, "blue" sends values from 0-255, "red" from 256-511, "white" from 512-767. As a delimiter between the numbers I use *. If I use the following code, it all works perfectly fine:

#include <SoftwareSerial.h>

SoftwareSerial btSerial(2, 3); // RX, TX PIN

String bt_rx;
int ledpin = 11;
int data = 0;
int writeData = 0;
int received = 0;

void setup() {
  Serial.begin(9600);
  pinMode(ledpin, OUTPUT);
  btSerial.begin(9600);
}

void loop() {
  if (btSerial.available()) {
    bt_rx = btSerial.readStringUntil("*"); //read signal up to delimiter
    Serial.println("Received:");
    received = bt_rx.toInt(); //convert to int
    data = bt_rx.toInt()%256; //separate the data from the pin number 
     
    writeData = (data*data)/255; //scale the data to get smoother fading
    Serial.println(bt_rx);  
    Serial.println(writeData);
    
  }
  
  analogWrite((received - data)/256 + 9, writeData);
}

But if I want to calculate the pin number in a variable and change the last to lines of code to

  ledpin = (received - data)/256 + 9; //calculate the pin number
  analogWrite(ledpin, writeData);

the readStringUntil command seems to stop working correctly and the bt_rx variable contains not only one number but a string of numbers and *s, which means that the faders don't work the way I want them to.

Does anybody have an explanation for this behaviour. Of course I could simply use the first version of the sketch, but I want to build onto this to include other functions and I'm afraid I'll run into similar problems when I change or add other bits of code.

BTW: I'm rather new to Arduino programming, so go easy on me if I have overlooked something obvious.

Please, give an example of the string/data item that you are sending from the Android Smart Phone.

Why not send the data in a simpler and more obvious fashion - for example <122, 96, 37, 7> where the first three numbers are the values for red, green and blue and the last value is the led number.

Have a look at the parse example in Serial Input Basics

...R

Thanks a lot for your input.

When a slider of the app moves, it sends a string like
7476828494102105112148150153156
where the numbers indicate the positions of the slider until it stops moving. The app is done with MIT App Inventor and thats just the way sliders behave in this program.

In my first (working) version of the sketch, it produces output in the serial monitor looking like this (different values, of course):

Received:
371
51
Received:
361
43
Received:
358
40
Received:
348
33
Received:
340
27

This is what I am looking for, the fading of the LED follows the movement of the slider, every transmitted position is written to the output pin.

With the calculation of the pin number in a line by itself the output looks like this:

Received:
74*79*82*89*94*110*120*138*145*163*178*184*
21

Strangely enough, the pin number ist still calculated correctly, but the data written to it is unpredictable.

I could of course try and parse the data in a different way or change the app to produce a different data format, but since the first version of the sketch works perfectly and is rather easy to handle, I would still like to know what' going on here.

@OP

Thank you for the reply. I am still trying to understand your system before I do the experiment for myself.

Can you please tell/show me with an example data/string item (that is coming from your BT) how does the 1st argument (received - data)/256 + 9) of the following code (taken from your sketch) evaluate to Dpin-11?

analogWrite((received - data)/256 + 9, writeData);

toni12345:
When a slider of the app moves, it sends a string like
7476828494102105112148150153156
where the numbers indicate the positions of the slider until it stops moving

I suggest you don't do it like that as it is likely to overwhelm the communication system

Either wait until the slider stops and then send the value for that slider position
OR
send values at pre-determined time intervals - for example every 200 millisecs.

...R

GolamMostafa:
Can you please tell/show me with an example data/string item (that is coming from your BT) how does the 1st argument (received - data)/256 + 9) of the following code (taken from your sketch) evaluate to Dpin-11?

I'll try to explain: "received" is the int derived from the string sent before the first *. "data" is defined as received % 256, so if I subtract received - data, I get either 0 (first fader), 256 (second fader) or 512 (third fader). If I divide that by 256 and add 9, I get the pin number that I want.

Example: If the received number is 534 then

data = 22
(received - data) = 512

and I get 9+2 = 11 for the pin number.

Robin2:
Either wait until the slider stops and then send the value for that slider position

Might be possible, but I'd like to be able to monitor the constant change to the LED's brightness.

OR
send values at pre-determined time intervals - for example every 200 millisecs.

Could be a possible solution, but I am not sure how to do this in App Inventor.

In the meantime, I found out that the problem goes away if I declare "ledpin" as float! I'm still not sure what is going on here, but I think I can work with that solution at the moment. However, I'd still appreciate it if someone could tell me exactly what is going on.

toni12345:
I'll try to explain: "received" is the int derived from the string sent before the first *. "data" is defined as received % 256, so if I subtract received - data, I get either 0 (first fader), 256 (second fader) or 512 (third fader). If I divide that by 256 and add 9, I get the pin number that I want.

OK! It has worked well for 534*.

Let us see if the same logic works for 74* (Post#3 of your's).

received = 74
data = received%256 = 0.
received - data = 74 - 0 = 74
pin number = 74/256 + 9 = 9?

In your sketch, you have declared only one DPin which is 11.

Oh, I see what you mean! I actually forgot to declare the other two pins (9+10) in setup, and after doing that, the sketch works in the second version as well, even wothout using "float". :slight_smile:

I'm afraid I still don't understand what exactly is going on here and why it worked in the other version without declaring the other two pins. But for now I feel I can safely build on that and continue my project. Thanks a lot!

toni12345:
Oh, I see what you mean! I actually forgot to declare the other two pins (9+10) in setup, and after doing that, the sketch works in the second version as well, even without using "float". :slight_smile:

I'm afraid I still don't understand what exactly is going on here and why it worked in the other version without declaring the other two pins. But for now I feel I can safely build on that and continue my project. Thanks a lot!

But, be cautious! When there is something that does not work in theory, that will never work in practice. However, there may be something that works in practice; but, it would be very dangerous to put that thing into serious application without having/finding enough theoretical/empirical justification in favor of its functioning as the system might be containing ill-ingredients that would led to fail at any time catastrophically.