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;
}
}
}
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");
}
}
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.
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.
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.