Servos and other things all together

I have created an arduino vehicle which has 4 normal dc motors , 1 servo and all of which is controlled via bluetooth in my mobile phone.. The application is created via Mit app inventor. The thing is I have used strings to control the 4 dc motors all of which are working fine but as the servo motor require angle to move so when I sent numbers from the App my code can't differentiate between the string and the angle (number) I sent from the app and the servo starts to act crazy when I sent the command to control the dc motors. I know this is Dumb of me to ask this but I have been trying to solve this problem since so long.. Please help, doesn't need code just HELP..!!
Much appreciated,
Anshumaan.


#include <SoftwareSerial.h>
#include <Servo.h>
Servo myservo;
int Tx = 10;
int Rx = 11;
SoftwareSerial bluetooth(Tx, Rx);
const int input_1 = 2;
const int input_2 = 3;
const int input_3 = 4;
const int input_4 = 5;
const int cannon = 9;
String inputbyte;//this will be used to receive commands from the application...
void setup() {
  // put your setup code here, to run once:
  pinMode(input_1, OUTPUT);
  pinMode(input_2, OUTPUT);
  pinMode(input_3, OUTPUT);
  pinMode(input_4, OUTPUT);
  pinMode(cannon, OUTPUT);
  digitalWrite(input_1, LOW);
  digitalWrite(input_2, LOW);
  digitalWrite(input_3, LOW);
  digitalWrite(input_4, LOW);
  Serial.begin(9600);//turning on the bluetooth module...
  bluetooth.begin(9600);
  myservo.attach(cannon);
}

void loop() {
  // put your main code here, to run repeatedly:
  bluetooth_commands();
}
void bluetooth_commands(void)
{
  if(bluetooth.available() > 0)
  {
    inputbyte = bluetooth.read();
    int servo_value = bluetooth.read();
    myservo.write(servo_value);
    if(inputbyte == "forward")
    {
      //move forward...
      //all motors move forward
      //cancel other commands...
      //turning ON all the motors in same direction...
      digitalWrite(input_1, HIGH);
      digitalWrite(input_3, HIGH);
    }
    else if(inputbyte == "backward")
    {
      //move backward
      //all motors move backward
      digitalWrite(input_2, HIGH);
      digitalWrite(input_4, HIGH);
    }
    else if(inputbyte == "left")
    {
      //move left side
      //left side motors work and right side do not
      digitalWrite(input_3, HIGH);
    }
    else if(inputbyte == "right")
    {
      //move right side
      //right side motors work and left side do not 
      digitalWrite(input_1, HIGH);
    }
    else if(inputbyte == "stop")
    {
        digitalWrite(input_1, LOW);
        digitalWrite(input_2, LOW);
        digitalWrite(input_3, LOW);
        digitalWrite(input_4, LOW);
    }
   }
}

Depends on what you are sending but assuming something like
"left 30\n"
then try
in setup()

inputbyte.reserve(20);
bluetooth.setTimeout(100);  // timeout in 100mS

then in the loop()

if(bluetooth.available() > 0)
  {
   inputbyte = bluetooth.readStringUntil(' '); // read upto first space
   String value = bluetooth.readStringUntil('\n');
   value.trim();
    int servo_value = value.toInt();  // NOTE toInt() returns 0 on error so need some other check.
    if (value != String(servo_value)) {
      // error invalid int,  bad msg or something else
    }

also see Arduino Serial – Reading/Parsing

Your post was MOVED to its current location as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

Thanks for the quick reply drmpf. Yes you are right that I have been sending strings for the dc motors such as "forward", "backward", "left" and "right" and I have been sending numbers for the angle for the servo 0 to 170. I used your snippet like I understood and here is the result although it is showing the error :- request for member 'reserve' in 'input_byte', which is of non-class type 'int'
.. What I am doing wrong ?

shouldn't the code set complementary inputs when others are set HIGH? the only time your input pins (e.g. "input_2") are set low in for stop. shouldn't "input_3" be set LOW when "input_1" is set HIGH for "right"? should there be a "straight" command where both "input_3" and "input_1" are set LOW?

yes you are right but that process is being taken care of by the application itself whenever the user holds the button (for example forward button) arduino receives the string related to the button that is held (forward button sends "forward" string) and then when the user releases the button the app then sends the "stop" string and the stop function is called which turns all the outputs LOW..
I hope you get what I am trying to say..
For me all of the functions of the application as well as the arduino code are performing well except for the fact that the servo motor and dc motor commands are getting mixed up leading to messing up of the movement of both the motors....

UKHeliBob ok sir, I will try to learn the basics of posting in the arduino forum. Also thanks for the correction your correction will help me to find out the solution of my problem......
Now, drmpf sir, it took some time to understand your code and I have one question what is the error you are referring to when you made a comment that the ' .toInt()' function returns 0 on error. You must be saying that If the buffer doesn't receive any data from bluetooth then the function will return 0 which will move the servo to 0 degree. Have I understood that correctly??..

If your buffer is empty OR does not contain a leading number .e.g "abc" the toInt() returns 0
"55cd" will return 55 but that is probably still an error in your case.

Edit -- Very long numbers also give garbage results e.g.
"123456789012345" => -2045911175

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