help to Implement bluetooth in my code

Hi there, I need more help with my code as I'm trying to implement it with bluetooth capabilities.
I've created an app that sends a value via serial and I want that value to tell the Arduino to move the servo forward in this case by 160 degrees, I successfully achieved that with this code:

#include <SoftwareSerial.h> // TX RX software library for bluetooth

#include <VarSpeedServo.h> // servo library 
VarSpeedServo Left; // Left servo name
VarSpeedServo Right; // Right servo name
int bluetoothTx = 2; // bluetooth tx to 10 pin
int bluetoothRx = 3; // bluetooth rx to 11 pin
const int LeftServo = 7;  //Left Servo Pin
const int RightServo = 8; //Right Servo Pin

SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

void setup()
{
  Left.attach(LeftServo); // attach servo signal wire to pin 9
  Right.attach(RightServo);
  //Setup usb serial connection to computer
  Serial.begin(9600);

  //Setup Bluetooth serial connection to android
  bluetooth.begin(9600);
}

void loop()
{
  //Read from bluetooth and write to usb serial
  if(bluetooth.available()> 0 ) // receive number from bluetooth
  {

if (bluetooth.read()==160) { // read number sent by the app

            Right.write(160, 100, true); //writes the steps
            delay(100);
            Left.write(160, 100, true);
   }
  }
}

And I'm now trying to fit it in my code, but I'm getting stuck since I have an if and an else if but nothing else seems to work if i try to add extra conditionals, all I wanted to do is tell the Arduino that if there is a value of 160 or the digital read is high set the servo to go to 160.

//SETTINGS

//DELAY

int T1 = 500; // Forward delay in ms.
int T2 = 500; // Reverse delay in ms

//BUTTON SETTINGS

int InchStepsL = 5; // Inch rotation degrees 0-160
int InchStepsR = 5; // Inch rotation degrees 0-160
int HoldButton = 3000; // Hold button time for instant full rotation in ms

//SPEED

int Speed = 50; // Rotation speed 1-100 in ms

////SAFE ZONE
//
//int SafeZone = 100; // Safe zone position degrees 0-160
//                    // after power surge
                    
//CODE

//#include <Servo.h>
#include <VarSpeedServo.h> 
#include <SoftwareSerial.h> // TX RX software library for bluetooth

int bluetoothTx = 2; // bluetooth tx to 10 pin
int bluetoothRx = 3; // bluetooth rx to 11 pin

SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

VarSpeedServo Left;  //Left Servo Name
VarSpeedServo Right; //Right Servo Name

const int LeftServo = 7;  //Left Servo Pin
const int RightServo = 8; //Right Servo Pin

const int Forward = 4; //Forward Button Pin
const int Reverse = 6; //Reverse Button Pin

const int LOCK = 8; //Lock Pin

const int LeftPot = A0;  //Left Pot Pin
const int RightPot = A1; //Left Pot Pin

int LeftAngle =  0;
int RightAngle = 0;

void setup() {
  
  Serial.begin(9600);

  pinMode(Forward, INPUT_PULLUP);
  pinMode(Reverse, INPUT_PULLUP);
  pinMode(LOCK, OUTPUT);

  bluetooth.begin(9600);
  

//  LeftAngle = analogRead(LeftPot);
//  LeftAngle = map(LeftAngle, 1028, 0, 160, 0);
//  RightAngle = analogRead(RightPot);
//  RightAngle = map(RightAngle, 1028, 0, 160, 0);


  

  Left.attach(LeftServo);
  Right.attach(RightServo);

  Left.write(LeftAngle);
  Right.write(RightAngle);

  delay(1000);

//  Left.detach();
//  Right.detach();

  digitalWrite(LOCK, HIGH);
  
}

void loop() {

  if (bluetooth.read() == 160) { 

            Right.write(160, 100, true); 
            delay(100);
            Left.write(160, 100, true);
  }
  
  if (digitalRead(Forward) == HIGH) {
    Serial.println("FORWARD");
    Serial.println("");
    unsigned long StartF = millis();
    
    while (digitalRead(Forward) == HIGH) {
      Serial.println("FORWARD");
      Serial.println("");
      
    if (millis() - StartF < HoldButton) {
      digitalWrite(LOCK, LOW);
      Serial.println("LESS THAN 3 SECONDS(FORWARD)");
      Serial.println("");
      RightAngle += InchStepsR;
      LeftAngle += InchStepsL;

      if (RightAngle >= 160) {
        RightAngle = 160;
      }
       if (LeftAngle >= 160) {
        RightAngle = 160;
      }

      Right.attach(RightServo);
      Left.attach(LeftServo);
      
      Right.write(RightAngle, Speed, true);
      delay(T2);
      Left.write(LeftAngle, Speed, true);

      delay(500);

      Left.detach();
      Right.detach();

      digitalWrite(LOCK, HIGH);
      
    }

    else if (millis() - StartF >= HoldButton) {
      digitalWrite(LOCK, LOW);
      Serial.println("MORE THAN 3 SECONDS(FORWARD)");
      Serial.println("");
      RightAngle = 160;
      LeftAngle = 160;
      
      Right.attach(RightServo);
      Left.attach(LeftServo);
      
      Right.write(RightAngle, Speed, true);
      delay(T2);
      Left.write(LeftAngle, Speed, true);
      
      delay(1000);

      Left.detach();
      Right.detach();

      digitalWrite(LOCK, HIGH);
      
    }
   }
  }

  if (digitalRead(Reverse) == HIGH) {
    Serial.println("REVERSE");
    Serial.println("");
    unsigned long StartR = millis();
    
    while (digitalRead(Reverse) == HIGH) {
      Serial.println("REVERSE");
      Serial.println("");
    
    if (millis() - StartR < HoldButton) {
      digitalWrite(LOCK, LOW);
      Serial.println("LESS THAN 3 SECONDS(REVERSE)");
      Serial.println("");

      RightAngle -= InchStepsR;
      LeftAngle -= InchStepsL;

      if (RightAngle <= 0) {
        RightAngle = 0;
        
      }
      
      if (LeftAngle <= 0) {
        LeftAngle = 0;
        
      }

      Left.attach(LeftServo);
      Right.attach(RightServo);

      Left.write(LeftAngle, Speed, true);
      delay(T1);
      Right.write(RightAngle, Speed, true);

      delay(500);

      Left.detach();
      Right.detach();

      digitalWrite(LOCK, HIGH);
      
    }

    else if (millis() - StartR >= HoldButton) {
      digitalWrite(LOCK, LOW);

      Serial.println("MORE THAN 3 SECONDS(REVERSE)");
      Serial.println("");

      RightAngle = 0;
      LeftAngle = 0;

      Left.attach(LeftServo);
      Right.attach(RightServo);

      Left.write(LeftAngle, Speed, true);
      delay(T1);
      Right.write(RightAngle, Speed, true);

      delay(1000);

      Left.detach();
      Right.detach();

      digitalWrite(LOCK, HIGH);
      
    }
   }
  }
 }

Obviously how the code is setup now it won't work I just left the two if's at the start of the loops as I'm not sure how to fix it, I've tried to put and, or and to put one if, one else and one else if but it doesn't work, so what do you guys think?

Thanks :slight_smile: :slight_smile:

all I wanted to do is tell the Arduino that if there is a value of 160 or the digital read is high set the servo to go to 160.

You appear to have left the checking if anything is available to read from bluetooth

if(bluetooth.available()> 0 ) // receive number from bluetooth
  {

if (bluetooth.read()==160) { // read number sent by the app

            Right.write(160, 100, true); //writes the steps
            delay(100);
            Left.write(160, 100, true);
   }
  }

Obviously how the code is setup now it won't work

It's not obvious to me. The two if conditionals are independent and should work like "or".

Does your code work as you wish without the bluetooth added?

What is the exact problem with the posted code?

What does it not do that you want it to do?

What does it actually do that you do not want it to do?

The following statement likely does not do what you think it does.

if (bluetooth.read()==160) { // read number sent by the app

Have a look at the documentation.

Returns
The first byte of incoming serial data available (or -1 if no data is available). Data type: int.

So, unless you are sending a single byte with a value of 160 this will not work.

A few notes about your code.

  • try to remove all delay in your code, you are using millis() already, stick with it, it will be better in the long run

  • You use while(). Try to make your code run with if(). While loops are often blocking code and make extending it harder. Try to make the loop function run as often as possible.

  • Your code indentation is not correct. Try the Tools -> AutoFormat. It is like magic and can be configured to fit your code style preferences.

  • You code size suggests you are ready for using functions. Give it a try.

Your variable naming could use some improvements to increase readability e.g.

  • Left and Right are not good variable names e.g. think would the following statement work from a logical point of view

Right.write(160, 100, true);

You write 3 values to an abstract concept of right.

  • This must be confusing even for you. Maybe when you look at the code in a few weeks. :slight_smile:
VarSpeedServo Left;  //Left Servo Name
VarSpeedServo Right; //Right Servo Name

const int LeftServo = 7;  //Left Servo Pin
const int RightServo = 8; //Right Servo Pin

This would be easier to understand

VarSpeedServo LeftServo;
VarSpeedServo RightServo;

const int LeftServoPin = 7;
const int RightServoPin = 8;

I recommend you add "Pin" at the end of every variable containing the pin number. This way you can verify calls to pin functions very quickly.

  • Here is another statement that is hard to read without researching the code

if (millis() - StartF < HoldButton) {

What is StartF and why is a Button part of a timing calculation? Have a look at the examples code they use millis in the variable’s names on the left and "interval" at the right. You could also have "delay" or "time" on the right if the event is not repeated.

Your variable naming style is inconsistent. Have a look at the Arduino variable naming conventions. See if you like them. The two most important. Variables and functions start with a lower letter and then camelCase. Constants are ALL_CAPITAL_WITH_UNDERSCORE.

I found it was the servo.detach that was stopping the code from looping! thanks guys!

Klaus_K:
The following statement likely does not do what you think it does.

if (bluetooth.read()==160) { // read number sent by the app

Have a look at the documentation.

Serial.read() - Arduino Reference

So, unless you are sending a single byte with a value of 160 this will not work.

A few notes about your code.

  • try to remove all delay in your code, you are using millis() already, stick with it, it will be better in the long run

  • You use while(). Try to make your code run with if(). While loops are often blocking code and make extending it harder. Try to make the loop function run as often as possible.

  • Your code indentation is not correct. Try the Tools -> AutoFormat. It is like magic and can be configured to fit your code style preferences.

  • You code size suggests you are ready for using functions. Give it a try.

Your variable naming could use some improvements to increase readability e.g.

  • Left and Right are not good variable names e.g. think would the following statement work from a logical point of view

Right.write(160, 100, true);

You write 3 values to an abstract concept of right.

  • This must be confusing even for you. Maybe when you look at the code in a few weeks. :slight_smile:
VarSpeedServo Left;  //Left Servo Name

VarSpeedServo Right; //Right Servo Name

const int LeftServo = 7;  //Left Servo Pin
const int RightServo = 8; //Right Servo Pin




This would be easier to understand



VarSpeedServo LeftServo;
VarSpeedServo RightServo;

const int LeftServoPin = 7;
const int RightServoPin = 8;




I recommend you add "Pin" at the end of every variable containing the pin number. This way you can verify calls to pin functions very quickly.

- Here is another statement that is hard to read without researching the code

if (millis() - StartF < HoldButton) {

What is StartF and why is a Button part of a timing calculation? Have a look at the examples code they use millis in the variable’s names on the left and "interval" at the right. You could also have "delay" or "time" on the right if the event is not repeated.

Your variable naming style is inconsistent. Have a look at the Arduino variable naming conventions. See if you like them. The two most important. Variables and functions start with a lower letter and then camelCase. Constants are ALL_CAPITAL_WITH_UNDERSCORE.

Klaus_K:
The following statement likely does not do what you think it does.

if (bluetooth.read()==160) { // read number sent by the app

Have a look at the documentation.

Serial.read() - Arduino Reference

So, unless you are sending a single byte with a value of 160 this will not work.

A few notes about your code.

  • try to remove all delay in your code, you are using millis() already, stick with it, it will be better in the long run

  • You use while(). Try to make your code run with if(). While loops are often blocking code and make extending it harder. Try to make the loop function run as often as possible.

  • Your code indentation is not correct. Try the Tools -> AutoFormat. It is like magic and can be configured to fit your code style preferences.

  • You code size suggests you are ready for using functions. Give it a try.

Your variable naming could use some improvements to increase readability e.g.

  • Left and Right are not good variable names e.g. think would the following statement work from a logical point of view

Right.write(160, 100, true);

You write 3 values to an abstract concept of right.

  • This must be confusing even for you. Maybe when you look at the code in a few weeks. :slight_smile:
VarSpeedServo Left;  //Left Servo Name

VarSpeedServo Right; //Right Servo Name

const int LeftServo = 7;  //Left Servo Pin
const int RightServo = 8; //Right Servo Pin




This would be easier to understand



VarSpeedServo LeftServo;
VarSpeedServo RightServo;

const int LeftServoPin = 7;
const int RightServoPin = 8;




I recommend you add "Pin" at the end of every variable containing the pin number. This way you can verify calls to pin functions very quickly.

- Here is another statement that is hard to read without researching the code

if (millis() - StartF < HoldButton) {

What is StartF and why is a Button part of a timing calculation? Have a look at the examples code they use millis in the variable’s names on the left and "interval" at the right. You could also have "delay" or "time" on the right if the event is not repeated.

Your variable naming style is inconsistent. Have a look at the Arduino variable naming conventions. See if you like them. The two most important. Variables and functions start with a lower letter and then camelCase. Constants are ALL_CAPITAL_WITH_UNDERSCORE.

Klaus_K:
The following statement likely does not do what you think it does.

if (bluetooth.read()==160) { // read number sent by the app

Have a look at the documentation.

Serial.read() - Arduino Reference

So, unless you are sending a single byte with a value of 160 this will not work.

A few notes about your code.

  • try to remove all delay in your code, you are using millis() already, stick with it, it will be better in the long run

  • You use while(). Try to make your code run with if(). While loops are often blocking code and make extending it harder. Try to make the loop function run as often as possible.

  • Your code indentation is not correct. Try the Tools -> AutoFormat. It is like magic and can be configured to fit your code style preferences.

  • You code size suggests you are ready for using functions. Give it a try.

Your variable naming could use some improvements to increase readability e.g.

  • Left and Right are not good variable names e.g. think would the following statement work from a logical point of view

Right.write(160, 100, true);

You write 3 values to an abstract concept of right.

  • This must be confusing even for you. Maybe when you look at the code in a few weeks. :slight_smile:
VarSpeedServo Left;  //Left Servo Name

VarSpeedServo Right; //Right Servo Name

const int LeftServo = 7;  //Left Servo Pin
const int RightServo = 8; //Right Servo Pin




This would be easier to understand



VarSpeedServo LeftServo;
VarSpeedServo RightServo;

const int LeftServoPin = 7;
const int RightServoPin = 8;




I recommend you add "Pin" at the end of every variable containing the pin number. This way you can verify calls to pin functions very quickly.

- Here is another statement that is hard to read without researching the code

if (millis() - StartF < HoldButton) {

What is StartF and why is a Button part of a timing calculation? Have a look at the examples code they use millis in the variable’s names on the left and "interval" at the right. You could also have "delay" or "time" on the right if the event is not repeated.

Your variable naming style is inconsistent. Have a look at the Arduino variable naming conventions. See if you like them. The two most important. Variables and functions start with a lower letter and then camelCase. Constants are ALL_CAPITAL_WITH_UNDERSCORE.

Thanks for pointing out the issues but some are not clear, since is a code for a window automation what would I call the left and right window motor?
Right.write(160, 100, true);
This was just for testing purposes as you can see further down in the code it's done differently
How would you use the millis instead of delay?

floxia:
Thanks for pointing out the issues but some are not clear, since is a code for a window automation what would I call the left and right window motor?

The answer is right in front of your eyes just a few lines below. :slight_smile: LeftServo instead of calling the pin LeftServo. And call the pin LeftServoPin.

floxia:
How would you use the millis instead of delay?

You have to rethink the way you write your sketch. Until now you have written your program like you would tell a human to do a single job. Many humans will be happy to get a break while working. Your Arduino is not a human it is a machine that can execute all instructions you can store in its entire memory in less than one second (often even one millisecond) and it does not mind not having any breaks. You need to write the code in a way that the Arduino looks at every task again and again and only does what needs to be done in the moment. Let’s start with one task.

Try to write a function that does the following things. (Do one step after another. Use a separate sketch.)

  1. first when the function is called it just returns
  2. next when you set a variable to 1 it sets the variable back to zero and then switches the Arduino LED On
  3. next when you call the function again and again for 5 seconds the function just returns
  4. finally after 5 seconds the function switches the LED Off and then the behavior starts at the beginning

Hints:

  • you can create a variable inside a function that will remember the value by using the "static" keyword
void myFunction()
{
  static int state = 0; // This variable will only be 0 the very first time

  state++; // State will increase every time the function is called
}
  • each number above describes a state
  • you can use if() or switch() to test the state
  • you can store the time the function run last time with millis() in a static variable

I'll look into functions, this is the first time I write a code and it took me quite a fair bit so I'll might need to study a bit more before I can do what you have explained!

floxia:
I'll look into functions, this is the first time I write a code and it took me quite a fair bit so I'll might need to study a bit more before I can do what you have explained!

Don't worry, get started and when you get stuck post the code and I help you along the way. If you prefer I can create a short example for you, but I believe it will be a better learning exercise when you build this example from scratch.