Problem with BLE, slider to byte, and now build export crashing on phone

Hi fellow app inventors

I'm new to the world of BLE and app's so first off all thank you MIT for making this possible and creating an amazing online tool.

I'm having the following issues i'm kind of stuck with to continue my project. I'm building a machine which can shoot tennis balls using 4 motors controlled over PWM.

2 motors that determine the speed and spin of the ball and a linear actuator to determine the height it needs to shoot the ball. Later there will also be a feeding system which supplies balls at variable speeds.


This is the first part, I drew and build it completely myself and had the aluminium CNC cut. I also changed the inlet on this picture later because I was having some trouble letting the balls go through fluently.


This is the actuator I'll be using, most of the parts are salvaged, this one is from and old hairdressers chair.

This is my arduino code:

#include <ArduinoBLE.h>

//declare I/O pins (these are not correct anymore and need to be changed)
const int led = LED_BUILTIN;
const int upper_motor_pwm = 16;  //pwm output speed of upper motor
const int upper_motor_dir = 17;  //digital output direction of upper motor
const int upper_motor_pot = A1;  //analog value input to control upper motor speed

const int lower_motor_pwm = 18;  //pwm output speed of lower motor
const int lower_motor_dir = 19;  //digital output direction of lower motor
const int lower_motor_pot = A2;  //analog value input to control lower motor speed

const int feed_motor_pwm = 20;  //pwm output speed of feed motor
const int feed_motor_dir = 23;  //digital output direction of feed motor
const int feed_motor_pot = A0;  //analog value intput to control feed motor speed

const int angle_motor_pwm = 22;   //pwm output speed of actuator motor
const int angle_motor_dir = 21;   //digital output direction of actuator motor
const int angle_motor_up = 0;     //button input actuator extend
const int angle_motor_down = 1;   //button input actuator retract
const int angle_motor_speed = 5;  //button input half speed of the actuator

//variables to store speed in
byte var_upper_motor;

BLEService volley_vendor_service("68743AD1-BABE-4EBE-BD6B-E7AFA8BAD20F");  //create service

BLEByteCharacteristic upper_motor_speed_characteristic("931D4446-F7BC-49B1-BB95-328F6936FE33", BLEWrite | BLERead | BLENotify);
BLEByteCharacteristic upper_motor_speed_status("23028CF2-6C30-4378-AA77-476BE3649250", BLEWrite | BLERead | BLENotify);

void setup() {
  pinMode(upper_motor_pwm, OUTPUT);
  pinMode(upper_motor_dir, OUTPUT);
  pinMode(upper_motor_pot, INPUT);

  pinMode(lower_motor_pwm, OUTPUT);
  pinMode(lower_motor_dir, OUTPUT);
  pinMode(lower_motor_pot, INPUT);

  pinMode(feed_motor_pwm, OUTPUT);
  pinMode(feed_motor_dir, OUTPUT);
  pinMode(feed_motor_pot, INPUT);

  pinMode(angle_motor_pwm, OUTPUT);
  pinMode(angle_motor_dir, OUTPUT);
  pinMode(angle_motor_up, INPUT);
  pinMode(angle_motor_down, INPUT);
  pinMode(angle_motor_speed, INPUT);
  pinMode(led, OUTPUT);

  // begin initialization
  if (!BLE.begin()) {
    Serial.println("BLE Module boot fail...");
    while (1)
      ;
  }

  // set the local name peripheral advertises
  BLE.setLocalName("Volley Vendor Machine");

  // set the UUID for the service this peripheral advertises:
  BLE.setAdvertisedService(volley_vendor_service);

  // add the characteristics to the service
  volley_vendor_service.addCharacteristic(upper_motor_speed_characteristic);  //slider
  volley_vendor_service.addCharacteristic(upper_motor_speed_status);  //feedback return value

  // add the service
  BLE.addService(volley_vendor_service);

  //set everything to zero to start
  upper_motor_speed_characteristic.writeValue(0);

  // start advertising
  BLE.advertise();

  // Initialize Serial communication
  Serial.begin(9600);
  Serial.println("Volley Vendor Machine started");
  Serial.println("Connect phone using the app");
}

void loop() {
  BLEDevice central = BLE.central();
  if (central) {
    digitalWrite(led, HIGH);
  }
  while (central.connected()) {
    upper_motor_speed_characteristic.readValue(var_upper_motor);
    if (var_upper_motor > 100) {
      digitalWrite(led, HIGH);
      delay(100);
      digitalWrite(led, LOW);
      delay(100);
      Serial.println(var_upper_motor);
    }
    Serial.println(var_upper_motor);
    upper_motor_speed_status.writeValue(var_upper_motor);
    delay(50);
  }
  digitalWrite(led, LOW);
}

So to get to my problem:
I've been trying to get the BLE set up but only for one motor at first and I want to control it using a slider right now. If I manually set a random value in my code from my arduino to my phone, I can receive it and see it in my label. (both in the variable and the .writeValue) so this works.
So I guess the problem lies within sending the value from the slider towards my arduino.

This is the MITAI block code i'm using now:

So to continue this problem further, the app won't fully start anymore.
I can get to the start scanning screen, see the list of devices and select my arduino, when connected the builtin led comes on like programmed in the code, but then completely crashes and the led goes out.

I'm using an arduino R4 wifi/bluetooth if it is any help.

Thank you in advance

(Canned Reply: ABG- Export & Upload .aia)
Export your .aia file and upload it here.
export_and_upload_aia

Sliders have been known to trigger more often than can be handled.
An Alternative approach is to use a Clock Timer to check the Slider Thumb position and only send its value if it has changed since the last cycle. Add an extra global variable for the previous value.

Also, it is a good idea to verify connection before trying to send something.

Be sure your BLE version is current:

You might not need that permission code if you are using the current BLE extension.

Hi

I'm using the latest build of the BLE Release.

This is my project file, sorry I forgot to add it.
Volley_Vendor_Machine.aia (198.7 KB)

I will remove the permission code and try this.
Thank you

No Luck app still crashes. I'm going to look into the clock timer for the sliders.

Would this be a good use of the timer then?


Thank you in advance

Use the Thumb value of the Slider component for your comparison, and for saving the last value.

That second global variable with the illegal empty number block is counterproductive.

Alternatively, init it to 0 and keep the code as is.

Here are 4 event blocks you could use to improve visibility into what's going on in your app:
component_event (1)


component_event

Add extra Labels to your app and/or a Notifier for diagnostic output.

Okay thank you I will try this, it crashes to my home page, so labels won't have any use I think. It strange, it worked well for so long. Maybe the notifier will still work

Until a more advanced BLE user can chime in, here are more advanced debugging options, including Logcat:

Okay I was able to fix the crashing, I missed one character in my UUID, very stupid mistake sorry about this. 🥲

I'm still having issues with the slider sending the value's to my arduino tho, I've set the limits from 0 to 255, which should fit inside a byte

What kind of issues are these? Please elaborate...
And what about providing a screenshot of your updated blocks?

Taifun

Hi Taifun

Thank you for your reply

These are my updated blocks, on my arduino serial monitor I keep receiving "0" no matter the slider position. On my feedback to the app on my phone this is also "0".

If I change "upper_motor_speed_characteristic.writeValue(0);" in arduino to like 104 the led starts blinking and I see the feedback on my phone.

Thank you in advance

I've added this block and can see it actually writes data now.

So it must be the arduino code now right?

Hi Everybody

I was able to fix my problem

I used the following arduino code if someone else has this problem.

#include <ArduinoBLE.h>

//declare I/O pins

const int led = LED_BUILTIN;

//const int upper_motor_pwm = 16;  //pwm output speed of upper motor
//const int upper_motor_dir = 17;  //digital output direction of upper motor
//const int upper_motor_pot = A1;  //analog value input to control upper motor speed

//const int lower_motor_pwm = 18;  //pwm output speed of lower motor
//const int lower_motor_dir = 19;  //digital output direction of lower motor
//const int lower_motor_pot = A2;  //analog value input to control lower motor speed

//const int feed_motor_pwm = 20;  //pwm output speed of feed motor
//const int feed_motor_dir = 23;  //digital output direction of feed motor
//const int feed_motor_pot = A0;  //analog value intput to control feed motor speed

//const int angle_motor_pwm = 22;   //pwm output speed of actuator motor
//const int angle_motor_dir = 21;   //digital output direction of actuator motor
//const int angle_motor_up = 0;     //button input actuator extend
//const int angle_motor_down = 1;   //button input actuator retract
//const int angle_motor_speed = 5;  //button input half speed of the actuator

//variables to store speed in
byte var_upper_motor;
//byte var_lower_motor;
//byte var_feed_motor;
//byte var_angle_motor;

BLEService volley_vendor_service("68743AD1-BABE-4EBE-BD6B-E7AFA8BAD20F");  //create service

BLEByteCharacteristic upper_motor_speed_characteristic("931D4446-F7BC-49B1-BB95-328F6936FE33", BLEWriteWithoutResponse | BLERead | BLENotify);
//BLEByteCharacteristic lower_motor_speed_characteristic("fe1885d6-ec0a-4350-9174-f28a01023170", BLEWrite | BLERead | BLENotify);
//BLEByteCharacteristic feed_motor_speed_characteristic("0a3f144d-e683-4d35-b39c-179918c79599", BLEWrite | BLERead | BLENotify);
//BLEByteCharacteristic angle_motor_up_characteristic("1d9bc3f7-1cca-4b70-b37b-0c12a085f811", BLEWrite | BLERead | BLENotify);
//BLEByteCharacteristic angle_motor_down_characteristic("3aebfa09-2991-4764-a5ee-8b4b6d275306", BLEWrite | BLERead | BLENotify);
//BLEByteCharacteristic angle_motor_slow_characteristic("4907f986-c71b-4831-beb6-55f087d3c0e7", BLEWrite | BLERead | BLENotify);
BLEByteCharacteristic upper_motor_speed_status("23028CF2-6C30-4378-AA77-476BE3649250", BLEWriteWithoutResponse | BLERead | BLENotify);
//BLEByteCharacteristic lower_motor_speed_status("9ea4a243-fb36-4a50-af17-a6a580ed3281", BLEWrite | BLERead | BLENotify);
//BLEByteCharacteristic feed_motor_speed_status("9245c4ed-58eb-4146-b954-e10a267a2d3a", BLEWrite | BLERead | BLENotify);

void setup() {
  /*pinMode(upper_motor_pwm, OUTPUT);
  pinMode(upper_motor_dir, OUTPUT);
  pinMode(upper_motor_pot, INPUT);

  pinMode(lower_motor_pwm, OUTPUT);
  pinMode(lower_motor_dir, OUTPUT);
  pinMode(lower_motor_pot, INPUT);

  pinMode(feed_motor_pwm, OUTPUT);
  pinMode(feed_motor_dir, OUTPUT);
  pinMode(feed_motor_pot, INPUT);

  pinMode(angle_motor_pwm, OUTPUT);
  pinMode(angle_motor_dir, OUTPUT);
  pinMode(angle_motor_up, INPUT);
  pinMode(angle_motor_down, INPUT);
  pinMode(angle_motor_speed, INPUT);*/
  pinMode(led, OUTPUT);

  // begin initialization
  if (!BLE.begin()) {
    Serial.println("BLE Module boot fail...");
    while (1)
      ;
  }

  // set the local name peripheral advertises
  BLE.setLocalName("Volley Vendor Machine");

  // set the UUID for the service this peripheral advertises:
  BLE.setAdvertisedService(volley_vendor_service);

  // add the characteristics to the service
  volley_vendor_service.addCharacteristic(upper_motor_speed_characteristic);  //slider
  //volley_vendor_service.addCharacteristic(lower_motor_speed_characteristic);  //slider
  //volley_vendor_service.addCharacteristic(feed_motor_speed_characteristic);   //slider
  //volley_vendor_service.addCharacteristic(angle_motor_up_characteristic);     //button
  //volley_vendor_service.addCharacteristic(angle_motor_down_characteristic);   //button
  //volley_vendor_service.addCharacteristic(angle_motor_slow_characteristic);   //switch
  volley_vendor_service.addCharacteristic(upper_motor_speed_status);  //feedback return value
  //volley_vendor_service.addCharacteristic(lower_motor_speed_status);          //feedback return value
  //volley_vendor_service.addCharacteristic(feed_motor_speed_status);           //feedback return value

  // add the service
  BLE.addService(volley_vendor_service);

  //set everything to zero to start
  upper_motor_speed_characteristic.writeValue(0);  //OK werkt
  //lower_motor_speed_characteristic.writeValue(0);
  //feed_motor_speed_characteristic.writeValue(0);
  //angle_motor_up_characteristic.writeValue(0);
  //angle_motor_down_characteristic.writeValue(0);
  //angle_motor_slow_characteristic.writeValue(0);

  // start advertising
  BLE.advertise();

  // Initialize Serial communication
  Serial.begin(9600);
  Serial.println("Volley Vendor Machine started");
  Serial.println("Connect phone using the app");
}

void loop() {
  BLE.poll();

  if (upper_motor_speed_characteristic.written()) {
    upper_motor_speed_characteristic.readValue(var_upper_motor);
    if (var_upper_motor > 100) {
      digitalWrite(led, HIGH);
      delay(100);
      digitalWrite(led, LOW);
      delay(100);
      Serial.println(var_upper_motor);
    } else {
      digitalWrite(led, LOW);
    }
    Serial.println(var_upper_motor);
    upper_motor_speed_status.writeValue(var_upper_motor);
    delay(50);
  }
}

I needed to change the write permission to BLEWriteWithoutResponse in my characteristic and use BLE.poll(); to look for any events. The blocks in MIT app inventor remained the same.

Hope this might help someone else too someday. :blush:

In the Clock Timer you compare the unrounded thumb to the rounded previous thumb

If the thumb settles into a fractional value, the Timer will continue to transmit until it's thumb settles on a round value.

The prior comparison should be rounded vs rounded.

1 Like

Oh Thank you I will adjust this too!

P.S. Thank you for telling us what worked.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.