Servo 180 deg and Bluetooth (MIT App Inventor)

Hello, I have been trying to control 180 degree servo (NOT continuous servo) using Bluetooth. My condition is using Bluetooth and two button from MIT App Inventor as follows:

  1. one button to turn the servo clockwise until it stops at max/min value and the other button to turn the servo counter-clockwise until it stops at max/min value.
    2)the servo will ONLY turn as long as I press (hold) the button. If I release the button, the servo will stop spinning and hold its current position.

For example, the servo is now at 45 deg. If I press (hold) the counter-clockwise button, the servo will continuously turn towards 180 degree; but if I release the button, even if the servo has not reached 180 degree, it will stop and hold its current position (pressing the same button again will repeat the process until the servo reaches its max position (180 deg).

But so far I only manage as follows: From 45 deg, the servo will turn to 50 deg (with +5 deg increment) every time I press (or hold) the button. If I want it to turn to certain angle, i have to repeatedly mash the button (turning it to 60 deg means I have to push it 3 times).

Is there anyway to achieve what I want? Thanks a lot.

Here's my current code:

#include <Servo.h>

Servo servo;

int angle =90;

char command;

void setup() {
servo.attach(A0);
servo.write(angle);
Serial.begin(9600);
}

void loop() {
if(Serial.available()) {
command = Serial.read();

if(command == 'a'){
    if (angle >= 0 && angle <= 180) {
      angle = angle - 5;
       if(angle < 0){
        angle = 0;
       }
      servo.write(angle);  
      delay(100);
    }
}

if(command == 'b'){
    if (angle >= 0 && angle <= 180) {
      angle = angle + 5;
      if(angle > 180){
        angle = 180;
       }
      servo.write(angle);  
      delay(100);
    }
}

if(command == '0'){
servo.write(angle);  
delay(100);
}

}
}

You can first make a for loop to move a value of 5 degrees in the servo and then say motor .write the variable that you put in the for loop
This is in short, as I understand it

and in the for loop, you will write i+5 or i-5

Hi!

This question is more related to your app than to your Arduino code - which is doing what it was wrote to do, except for this part:

I think it´s useless, since you´ve mentioned only 2 buttons in the app (a and b I guess). How/when was Arduino supposed to receive '0'?

Each time a button is pressed (or held) at the app, it sends a command to the arduino, but the command will not be repeated in the app unless you release the button and press it again.

I would follow one of these 2 paths:

  1. create a third button (stop) on the app and modify your Arduino code to repeat 'a' or 'b' until button 'stop' is pressed. This way you would click once in the button and servo would keep moving until you press stop.

OR

  1. use a different feature in the MIT app like LongClick() or TouchUp() to detect if the button is held and repeat sending the command while the button is pressed. In this case, you should consider that using delay() at the code can cause some side effects, related to receiving and buffering the commands.

I would go for (1)...

Have fun! :upside_down_face:

Both 'a' and 'b' button commands are TouchDown (when buttons are pressed, they send 'a' and 'b' respectively). As for '0' is TouchUp (when I release the buttons). I think that TouchUp is the "stop" function. How would you suggest I write the arduino code for "stop" function?

I have been considering to search on Google about "continuously sending string of texts via Bluetooth when button is pressed", but I prioritize on modifying the Arduino code first (unless there is really no other way).

Ok, I got the idea. It would work well if keeping the button pressed meant keep sending the command . But it doesn´t work this way.

Modify your Arduino code to repeat 'a' or 'b' until the button is released and send '0'.

The "stop function" did not work out well.. Nevertheless, I managed to achieve what I want by modifying the Block function in MIT App Inventor (thanks to someone posting the solution in MIT App Inventor forum). Basically, as long as I push the button, the app will continuously send command string to Arduino with the help of clock timer (example : every 100 ms sending the same command to Arduino via Bluetooth), causing the servo to rotate every 100 ms as a result.

I thought I might share both of my Arduino code and my MIT App Inventor Block function here for those who might need it in the future for references.

#include <Servo.h>

Servo servo;

int angle = 90; //set servo to middle position

char command;

void setup() {
servo.attach(A0); // servo pin
Serial.begin(9600);
}

void loop() {
if(Serial.available()) {
command = Serial.read();

if(command == 'a'){
constrain(angle, 0, 180);
angle = angle + 3; //rotate to one direction
Serial.print(angle);
}

if(command == 'b'){
constrain(angle, 0, 180);
angle = angle - 3; //rotate to opposing direction
Serial.print(angle);
}

if(command == 'c'){
angle = 90; //set to middle position
Serial.print(angle);
}

servo.write(angle);
delay(100);
}
}

1 Like

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