Servo motor speed and bluetooth control

I'm trying to control a servo motor to extend and retract once at a certain speed through a bluetooth app. When I try to combine the bluetooth and movement coding, the motor will extend at its normal speed and then retract at the controlled slow speed. It also keeps going, instead of stopping after one iteration. My last issue is that also only the app button which sends a signal of '1' causes the motor to do anything, while the other one causes nothing. I'm suspecting these issues are all related to it somehow getting stuck in the sweep function, but I have limited coding knowledge and can't figure it out.

Also for reference, the movement and bluetooth code work correctly separately when I've tested them individually in simple ways, so I believe it has something to do with the way I am combining them.

Here is my code:

#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0; // stores servo position

#define actPin 9
int state = 0;

void setup() {
  myservo.attach(9); // attaches servo to pin 9

  pinMode(actPin, OUTPUT);
  Serial.begin(9600); // communication rate of bluetooth mod
}

void loop() {
  if (Serial.available() > 0) { // checks whether data is coming from the serial port
    state = Serial.read(); // reads the data coming from the serial port
  }
  if (state == '0') {
    for (int i = 0; i<1; i++) {
      for (pos = 0; pos <=180; pos += 1) { // goes from 0 to 180 degrees in steps of 1 degree
        myservo.write(pos); // tell servo to go to position in variable 'pos'
        delay(130); // control speed
      }
      Serial.println("Retracting");
      state = 0;
    }
  }
  else if (state == '1') {
    for (int n = 0; n<1; n++) {
      for (pos = 180; pos >=0; pos -= 1) { // goes from 180 to 0 degrees in steps of 1 degree
        myservo.write(pos); // tell servo to go to position in variable 'pos'
        delay(130); // control speed
      }
      Serial.println("Extending");
      state = 0;
    }
  }
}

Thank you for your help!

Are you sending anything other than 0 or 1, like CR/LF?

What Arduino board are you using?

Please post a schematic.

You do realize that it will take over 23 seconds to complete each sweep direction? Did you wait long enough?

Mixing data types?

Thanks for posting the code this good way.
Schematics are always good basic information telling about the powering of the project. Badly powered, no project will work whatever work is done to the code.

I think the issue is on the bluetooth side. When I test your program using input from the serial monitor, even with CR/LF terminators, I see correct one time operation of the servo sweeps.

Are you using a standard bluetooth terminal app or did you write some custom code?

I modified the code to use software serial for the Bluetooth module so that I can print debug information to the serial monitor and changed state to a char data type. See the code below. When run on my Uno with an HC05 BT module and servo and using the serial Bluetooth terminal app (CR/LF terminators enabled) I am getting the same results as @cattledog.

#include <Servo.h>
#include <SoftwareSerial.h>

SoftwareSerial ss(4, 7); // bt serial
Servo myservo; // create servo object to control a servo
int pos = 0; // stores servo position

#define actPin 9
char state = 0;  // was int

void setup()
{
   myservo.attach(9); // attaches servo to pin 9

   pinMode(actPin, OUTPUT);
   Serial.begin(9600);
   Serial.println("starting");
   ss.begin(9600);  // communication rate of bluetooth mod
   ss.println("starting");
}

void loop()
{
   if (ss.available() > 0)   // checks whether data is coming from the serial port
   {
      state = ss.read(); // reads the data coming from the serial port
      Serial.println(state);
   }
   if (state == '0')
   {
      Serial.println("Retracting");
      for (int i = 0; i < 1; i++)
      {
         for (pos = 0; pos <= 180; pos += 1)  // goes from 0 to 180 degrees in steps of 1 degree
         {
            myservo.write(pos); // tell servo to go to position in variable 'pos'
            delay(130); // control speed
         }
         state = 0;
      }
      Serial.println("Retracting done");
   }
   else if (state == '1')
   {
      Serial.println("Extending");
      for (int n = 0; n < 1; n++)
      {
         for (pos = 180; pos >= 0; pos -= 1)  // goes from 180 to 0 degrees in steps of 1 degree
         {
            myservo.write(pos); // tell servo to go to position in variable 'pos'
            delay(130); // control speed
         }
         state = 0;
      }
      Serial.println("Extending done");
   }
}

What is that for?

Hi,
Post a schematic of your project.
How are you powering the servo motor?
What micro controller are you using?

It is only sending a 0 or 1

I followed a custom code that somebody had posted online and have this:

import processing.serial.*;
Serial myPort;
String status="Not in progress";

void setup(){
  size(450, 500);
  myPort = new Serial(this, "COM4", 9600); // Starts the serial communication
  myPort.bufferUntil('\n'); // Defines up to which character the data from the serial port will be read. The character '\n' or 'New Line'
}
void serialEvent (Serial myPort){ // Checks for available data in the Serial Port
  status = myPort.readStringUntil('\n'); //Reads the data sent from the Arduino
}

void draw(){
  background(237, 240, 241);
  fill(20, 160, 133); // Green Color
  stroke(33);
  strokeWeight(1);
  rect(50, 100, 150, 50, 10);
  rect(250, 100, 150, 50, 10);
  fill(255);
  
  textSize(32);
  text("Extend",60, 135);
  text("Retract", 255, 135);
  textSize(24);
  fill(33);
  text("Status:", 180, 200);
  textSize(30);
  textSize(16);

  text(status, 155, 240); // Prints the string comming from the Arduino
  
  // If the button "Extend" is pressed
  if(mousePressed && mouseX>50 && mouseX<200 && mouseY>100 && mouseY<150){
    myPort.write('1'); // Sends the character '1' and that will extend the actuator
    // Highlighs the buttons in red color when pressed
    stroke(255,0,0);
    strokeWeight(2);
    noFill();
    rect(50, 100, 150, 50, 10);
  }
  // If the button "Retract" is pressed
  if(mousePressed && mouseX>250 && mouseX<400 && mouseY>100 && mouseY<150){
    myPort.write('0'); // Sends the character '0' and that will retract the actuator
    stroke(255,0,0);
    strokeWeight(2);
    noFill();
    rect(250, 100, 150, 50, 10);
  }
}

Thank you for your help, I had tried to follow a custom bluetooth app code since I don't have an android device to download that app on. Also, the for loop was my attempt make the sweep only go through once.

What is connected at COM4? Is it some sort of bluetooth adaptor?
How did you pair and connect to the HC05?

I paired the HC05 module to my computer and then it shows having connections through COM4-7

I have not worked with a pc bluetooth connection to an HC05, but this seems strange. I would expect that one serial port on the pc would be connected to an external bluetooth dongle or a bluetooth module inside the pc. If your program is writing to COM Port 4, how do you know that port is connected to the bluetooth transmitter which may be located at COM 4-7.

EDIT: See this tutorial. It shows only one COM port
https://avrgeeks.com/connect-arduino-with-computer-using-hc05/

I followed that procedure and confirmed that it is connected to COM4

Instead of your custom code, just use a simple PC terminal program like CoolTerm, RealTerm, or Putty to connect with COM 4 and see if you can send a simple '1' or '0'.

This was suggested in the tutorial before moving to a more complex program on the PC.

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