Movement and storage of servo positions via bluetooth

Goodmorning everyone,

I am trying to program a 4DOF robotic arm (using 4 servo motors). I would like to move the servos using an Android app, by means of bluetooth.
I developed the app, in whose interface there are 7 buttons (Up, Down, Left, Rght, Forward, Backward, Save) and a field in which you can type using the keyboard (I attach an image for clarity).
This is the code:

 #include <SoftwareSerial.h>
SoftwareSerial BT(10,11); // 10 RX, 11 TX
#include <Servo.h> 




char DataBT = ' ';




Servo servo01; 
byte pos01_i = 90, pos01_o; 
int servo01SP[50]; // for storing positions/steps
int index = 0;
#define ANGLE_STEP 10     // 10 degrees step




void setup() {
  Serial.begin(9600);
  BT.begin(9600);
  Serial.println("");
  Serial.println("Starting Control ...");
  servo01.attach(12);
  servo01.write(pos01_i); 
  servo01SP[0] = 90;  // Initial position




}




void loop() {




    if (BT.available()){
    DataBT = BT.read();
    Serial.println(DataBT);




    switch (DataBT){
    case('U'):
        Serial.println("UP");
          if (pos01_i <= 180 - ANGLE_STEP){
          pos01_o = pos01_i + ANGLE_STEP;
          delay(20); 
          break;
        }
    case ('D'):
      Serial.println("DOWN");
        if (pos01_i >= ANGLE_STEP){
        pos01_o = pos01_i - ANGLE_STEP; 
        delay(20);
        break;
    }  




   }
    servo01.write(pos01_o);
    Serial.println(pos01_o);
    pos01_i = pos01_o;
    delay(20);
  }
}

So far, I tried to manage only Up button (which sens 'U' via bluetooth to arduino) and Down (which sens 'D'), which would move the servo intended for vertical arm movements. That code works quite good, although the app crashes sometimes, but I still can't figure the reason out.

Seen that, what I would like to do now is: once I have moved the servo and reached a particular position, I'd like to save the position of the motor into an array. In order to allow multiple positions saving, after Save button is pressed, I want Arduino to wait for another input from the bluetooth (so that, it would wait for another button to be clicked from the app or for something typed into the dedicated bar from keyboard) that defines the position within the array, in which I save the servo position (eg: I type '2' into the dedicated app bar and Arduino, which is waiting for an input, receiving it, saves the last servo position into the array servo01pos[2]).

What I am not able to do is to make Arduino wait for a new bluetooth input when it receives 'S'. I tried several ways and searched in various forums, but I haven't yet been able to solve the problem.
This is the code of one of the many attempts made:

#include <SoftwareSerial.h>
SoftwareSerial bluetooth(10, 11); //BlueTooth RX ,TX
#include <Servo.h> 




unsigned long timestampSend = 0; // BT Write wait period
String readString;




Servo servo01; 
byte pos01_i = 90, pos01_o = 90; 
#define ANGLE_STEP 10     // 10 degrees step
int servo01pos[50];




void setup()
{
  Serial.begin(9600);
  bluetooth.begin(9600);
  delay(1000);
  Serial.print("Ready ...");
  Serial.print ("\n");
  servo01.attach(12);
  servo01.write(pos01_i);




}




void loop()
{




  if (millis() >= timestampSend + (1000)) // sending data over BT every 500mS
  {
    while (bluetooth.available())
    {
      delay(10);
      char data = bluetooth.read();
      readString += data;




      if (readString.length() > 0) {
      Serial.println("Received Value: " + readString);
      readString = ""; //clears variable for new input
      }
      
      switch(data){
       
        case ('S'): //SAVE
        while (bluetooth.available()){
        bluetooth.listen();
        char button = bluetooth.read();         // the number entered is the button (position) we want to save
        Serial.println("SAVING POSITIONS ...");
          if (button == '0'){
            servo01pos[0] = pos01_o;
          } else if (button == '1'){
            servo01pos[1] = pos01_o;
          } else if (button == '2'){
            servo01pos[2] = pos01_o;
          }
          servo01.write(pos01_o);
          Serial.println(pos01_o);
          Serial.println(servo01pos[1]);
        }
        break;
                
        case('U'):
        Serial.println("UP");
          if (pos01_i <= 180 - ANGLE_STEP){
          pos01_o = pos01_i + ANGLE_STEP;
          servo01.write(pos01_o);
          delay(20); 
        }
        break;
        
        case ('D'):
        Serial.println("DOWN");
          if (pos01_i >= ANGLE_STEP){
          pos01_o = pos01_i - ANGLE_STEP; 
          servo01.write(pos01_o);
          delay(20);
          }
        break;
      }




      delay(20);
      timestampSend = millis();
    }
  }
}

I hope I've been sufficiently clear. I apologize for the lack of synthesis.
Thanks in advance to who will answer me.

Giammarco

    case('U'):
        Serial.println("UP");
          if (pos01_i <= 180 - ANGLE_STEP){
          pos01_o = pos01_i + ANGLE_STEP;
          delay(20); 
          break;
        }
    case ('D'):

You should move the 'break;' statement to between case 'U': and case 'D':. Right now the 'break;' only happens if the 'U' has not hit the upper limit.

Make sure you have Compiler Warnings set to 'All' in Preferences. The compile will warn about many common programming mistakes.

Your sketch never changes "pos01_i" which is initialized to 90. That means 'pos01_o' will always change to 100 for 'U' and 80 for 'D'. Perhaps you don't need two variables to keep track of a single position. If you remove the '_i' and '_o' you should be able to move further.

Great! Thank you very much for you precious suggestions, I'll correct mistakes. What about the second part? Any suggestions?
Thank you all for your time.

To read a number, use serial.parseInt(). This will read until it finds digits or until it has been a full second since a character arrived.

        case ('S'): //SAVE
          button = bluetooth.parseInt();
          if (button >= 0 && button <= 2)
            servo01pos[button] = pos01;
          servo01.write(pos01_o);
          Serial.println(pos01_o);
          Serial.println(servo01pos[1]);
          break;

why not combine your data then send it so you ditch the waiting proses.
example: S20

in app
type "20" -> press S -> combine into "S20" -> Send "S20"

in arduino
Receive text = "S20" -> button = parsechar (text) , value = parseInt (text) -> button = "S", value = 20

inside case 'S'
pos_01 = value

johnwasser:
To read a number, use serial.parseInt(). This will read until it finds digits or until it has been a full second since a character arrived.

        case ('S'): //SAVE

button = bluetooth.parseInt();
         if (button >= 0 && button <= 2)
           servo01pos[button] = pos01;
         servo01.write(pos01_o);
         Serial.println(pos01_o);
         Serial.println(servo01pos[1]);
         break;

Really helpful! Thank you!

rzk:
why not combine your data then send it so you ditch the waiting proses.
example: S20

in app
type "20" -> press S -> combine into "S20" -> Send "S20"

in arduino
Receive text = "S20" -> button = parsechar (text) , value = parseInt (text) -> button = "S", value = 20

inside case 'S'
pos_01 = value

I could try to do so, it is a good way as well.
Thank you all for your time!

johnwasser:
To read a number, use serial.parseInt(). This will read until it finds digits or until it has been a full second since a character arrived.

        case ('S'): //SAVE

button = bluetooth.parseInt();
         if (button >= 0 && button <= 2)
           servo01pos[button] = pos01;
         servo01.write(pos01_o);
         Serial.println(pos01_o);
         Serial.println(servo01pos[1]);
         break;

I tried that one but the code, after received 'S', does not wait for entering a number.. I don't know why, after entered 'S', it directly jump to

          Serial.println(pos01_o);
          Serial.println(servo01pos[1]);
          break;

So, I wrote this new code that is quite long and inefficient but it works:

switch (data) {


          case ('S'): { //SAVE
              Serial.println("Enter the button you desire to set...");


              do {
                data = 254;
                bluetooth.listen();
                button = bluetooth.read();
                if (button == '0' || button == '1' || button == '2') {
                  data = 'S';
                }
              } while (data != 'S');


              Serial.println("SAVING POSITIONS ...");


              if (button == '0') {
                servo01pos[0] = pos01;
              } else if (button == '1') {
                servo01pos[1] = pos01;
              } else if (button == '2') {
                servo01pos[2] = pos01;
              }
              servo01.write(pos01);


              Serial.println(button);
              Serial.println(pos01);
              Serial.println(servo01pos[1]);
              Serial.println(servo01pos[2]);
              Serial.println(servo01pos[0]);
              //}
              break;
            }

Any thoughts? Thanks
Giammarco

I solved all my problems. So, thank you all for your time and help!
Giammarco