When the output from my BLE app arrives on the arduino its just gibberish

im trying to controll multiple servos with sliders and BLE

here are my code blocks

and here is what the output looks like on the serial monitor

ive tried using a lot of write functions like writeBytes, writeBytesWithResponse, writeIntegers, and much more, but it just gave me diffrent symbols

heres the code from the arduino side

#include <Servo.h>

#define servo1 2
#define servo2 3
#define servo3 4
#define servo4 5
#define servo5 6

Servo Mservo1;
Servo Mservo2;
Servo Mservo3;
Servo Mservo4;
Servo Mservo5;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Mservo1.attach(servo1);
Mservo2.attach(servo2);
Mservo3.attach(servo3);
Mservo4.attach(servo4);
Mservo5.attach(servo5);

Mservo1.write(90);
Mservo2.write(90);
Mservo3.write(90);
Mservo4.write(90);
Mservo5.write(90);

pinMode(servo1, OUTPUT);
pinMode(servo2, OUTPUT);
pinMode(servo3, OUTPUT);
pinMode(servo4, OUTPUT);
pinMode(servo5, OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly:

if(Serial.available()>0){
String Secondinput = Serial.readStringUntil('\n');
Serial.print( "SecondInput(" );
Serial.print( Secondinput );
Serial.println( ")." );
int RealServo = Secondinput.toInt();
Serial.print("Real Servo = ");
Serial.println(RealServo);

if(RealServo >= 1000 && RealServo <= 1180)
{
int Servo1Input = RealServo;
Servo1Input = map(Servo1Input, 1000, 1180, 0, 180);
Mservo1.write(Servo1Input);
Serial.print("servo 1 = ");
Serial.println(Servo1Input);
}
else if(RealServo >= 2000 && RealServo <= 2180)
{
int Servo2Input = RealServo;
Servo2Input = map(Servo2Input, 2000, 2180, 0, 180);
Mservo2.write(Servo2Input);
Serial.print("servo 2 = ");
Serial.println(Servo2Input);
}
else if(RealServo >= 3000 && RealServo <= 3180)
{
int Servo3Input = RealServo;
Servo3Input = map(Servo3Input, 3000, 3180, 0, 180);
Mservo3.write(Servo3Input);
Serial.print("servo 3 = ");
Serial.println(Servo3Input);
}
else if(RealServo >= 4000 && RealServo <= 4180)
{
int Servo4Input = RealServo;
Servo4Input = map(Servo4Input, 4000, 4180, 0, 180);
Mservo4.write(Servo4Input);
Serial.print("servo 4 = ");
Serial.println(Servo4Input);
}
else if(RealServo >= 5000 && RealServo <= 5180)
{
int Servo5Input = RealServo;
Servo5Input = map(Servo5Input, 5000, 5180, 0, 180);
Mservo5.write(Servo5Input);
Serial.print("servo 5 = ");
Serial.println(Servo5Input);
}
}
}

Try send
ServoTumbPosition join \n

Another idea:
https://community-appinventor-mit-edu.ezproxy.canberra.edu.au/t/ble-esp32-bluetooth-send-receive-arduino-ide-multitouch/1980/17

Use Slider extension:
https://community-appinventor-mit-edu.ezproxy.canberra.edu.au/t/free-open-source-slidertools-bit-of-useful-feature-for-sliders/17459

You are using the BLE block WriteIntegers, which sends 16 bit numbers internally coded in binary.

Your Arduino code is using

which reads text.

In your AI2 app, use the BLE block(s) that send text or Strings instead of integers.

1 Like

so because "round servo1 thumbposition" is a number it cant be sent with writeString(), so i tried changing the arduino code to read integers instead

if(Serial.available()>0){
int RealServo = Serial.parseInt();
Serial.print("Real Servo = ");
Serial.println(RealServo);

its not symbols anymore but it still gives me the wrong values in the serial monitor

am i using the wrong type of read?

AI2 has Duck Typing for numbers, so it is very generous with its conversion from numbers to text and vice versa.

Though the thumb position is a number, the BLE WriteStrings block should be able to convert the thumb value to a string before transmitting it.

  • WriteStrings – Writes one or more strings to a connected BluetoothLE device. Service Unique ID and Characteristic Unique ID are required. The values parameter can either be a single string or a list of strings. If utf16 is true, the string(s) will be sent using UTF-16 little endian encoding. If utf16 is false, the string(s) will be sent using UTF-8 encoding.Parameters:
    • serviceUuid (text) — The unique identifier of the service passed in the read or register call.
    • characteristicUuid (text) — The unique identifier of the characteristic in the read or register call.
    • utf16 (boolean) Send the string encoded as UTF-16 little endian (true) or UTF-8 (false) code points.
    • values (list) — A list of values to write to the device.

call BluetoothLE1 WriteStringsserviceUuidcharacteristicUuidutf16values

If I am wrong on this, I would love to hear about it and to see proof of it.

it cant convert int to string

as you can see on the bottom it says unable to convert 1164 (the value of thumbposition) to list

A List is not an integer - show us your code

i know its not, im not trying to convert to an integer, the integer is the rounded thumbposition and sending it through writeString doesnt convert it a string

heres the arduino code

#include <Servo.h>

#define servo1 2
#define servo2 3
#define servo3 4
#define servo4 5
#define servo5 6

Servo Mservo1;
Servo Mservo2;
Servo Mservo3;
Servo Mservo4;
Servo Mservo5;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Mservo1.attach(servo1);
Mservo2.attach(servo2);
Mservo3.attach(servo3);
Mservo4.attach(servo4);
Mservo5.attach(servo5);

Mservo1.write(90);
Mservo2.write(90);
Mservo3.write(90);
Mservo4.write(90);
Mservo5.write(90);

pinMode(servo1, OUTPUT);
pinMode(servo2, OUTPUT);
pinMode(servo3, OUTPUT);
pinMode(servo4, OUTPUT);
pinMode(servo5, OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly:

if(Serial.available()>0){
String Secondinput = Serial.readStringUntil('\n');
Serial.print( "SecondInput(" );
Serial.print( Secondinput );
Serial.println( ")." );
int RealServo = Secondinput.toInt();
Serial.print("Real Servo = ");
Serial.println(RealServo);

if(RealServo >= 1000 && RealServo <= 1180)
{
int Servo1Input = RealServo;
Servo1Input = map(Servo1Input, 1000, 1180, 0, 180);
Mservo1.write(Servo1Input);
Serial.print("servo 1 = ");
Serial.println(Servo1Input);
}
else if(RealServo >= 2000 && RealServo <= 2180)
{
int Servo2Input = RealServo;
Servo2Input = map(Servo2Input, 2000, 2180, 0, 180);
Mservo2.write(Servo2Input);
Serial.print("servo 2 = ");
Serial.println(Servo2Input);
}
else if(RealServo >= 3000 && RealServo <= 3180)
{
int Servo3Input = RealServo;
Servo3Input = map(Servo3Input, 3000, 3180, 0, 180);
Mservo3.write(Servo3Input);
Serial.print("servo 3 = ");
Serial.println(Servo3Input);
}
else if(RealServo >= 4000 && RealServo <= 4180)
{
int Servo4Input = RealServo;
Servo4Input = map(Servo4Input, 4000, 4180, 0, 180);
Mservo4.write(Servo4Input);
Serial.print("servo 4 = ");
Serial.println(Servo4Input);
}
else if(RealServo >= 5000 && RealServo <= 5180)
{
int Servo5Input = RealServo;
Servo5Input = map(Servo5Input, 5000, 5180, 0, 180);
Mservo5.write(Servo5Input);
Serial.print("servo 5 = ");
Serial.println(Servo5Input);
}
}
}

wrap the thumb position with a MAKE A LIST block.

image
is this right?

.... I meant you App code :innocent:

If you are using Serial.readStringUntil() in the Sketch, the value sent by the App can only be a single String, not a List (not an array).

So you have tried this:

Snap019

... and it results in the error you reported?

mutator

Remove the empty socket using the mutator

No, because your Sketch Code is processing only 1 string, not a List of Strings

yeah, how do you make it a string instead of a list?

The WriteStrings Block will send a single string or a List of strings. If you don't want a List, send a single value - or change how the data is received/processed in the Sketch.

Arduino C does not have particularly good string splitting functions.

is this really the best way of going about things? cant i just send it as an integer and read it also as an integer in the arduino code? the only problem with that is that it reads wrong

image

cant we just try to fix that?

First things first, did you try my App code snippet? Error or OK?

its an error

Please download and post each of those event block(s)/procedures here ...
(sample video)

Back to basics:

  1. How many integer values do you need to send from the App to the Arduino?
  2. Should they be sent in the same stream or individually?
  3. Why doesn't your Sketch have any BLE settings - UUIDs for example?
  4. What Arduino Model are you using?
  5. If your Arduino does not have built-in BLE, what BLE module/shield have you attached?

Please answer these question just as I have listed