Bluetooth shield

Hi all,

I have a question. For my master thesis, I'm building a wind turbine. (which is quite exciting ;)). For the engineering part, I need to control a Servo motor controlled by an Arduino Uno and a Bluetooth shield (v2.1). I basically need the Servo Sweep (example on Arduino software), and control it on my laptop. (Lenovo G50). Till now, I only got the right sweep at my Servo without using the Bluetooth part. It is really important for me to use the Servo wirelessly, so I hope some of you can help me with the programming of it. I read many articles about this, but I'm stuck for a week now... Could you please help me? Thanks in advance.

Freek

Show us the code that you tried. Describe what the code actually does and how that differs from what you want to do. What, specifically, do you need help with.

Before posting code, please read the “how to use the forum-please read” stickies to see how to format and post code.

The serial input basics thread might be of interest.

So basically, I tried to lighten up a LED. This succeeded through Bluetooth. I used this code:

void setup() {

// initialize serial:

Serial.begin(9600);

// initialize the LED pin

pinMode(13, OUTPUT);
        
}

void loop() {

while (Serial.available()) {

char inChar = (char)Serial.read();

switch(inChar) {

case '1':

digitalWrite(13, HIGH);

break;

case '0':

digitalWrite(13, LOW);

break;

}

Serial.println(inChar);

}

}

This is basic stuff, but I would like to get this code (a Servo sweep) to combine with the Bluetooth part.

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

The only thing I need to get is a delay and position dependent input for the Servo. Thanks in advance!

Do you have the Bluetooth shield set up to receive from the laptop? Once you have established communication between the two and can send from the laptop and have the Arduino receive a data packet use the parse example from the serial input basics thread (example #5) to pull out the position and delay.

The problem is, I'm a newbie in this stuff, and I find it very difficult to write something in Arduino. I can read (and understand) the code, but rewriting it is a bit difficult for me. I really thought it was easy to implement an example into a bluetooth signal, but unfortunately, that's not the case. Sadly, the examples that you gave were not giving me enough input to solve the problem. I think I should upload the servo instructions with USB to the Arduino, and after that, I can change the angle and the speed of the servo. However, I don't know how to do that... I'm really stuck, and I'm kinda frustrated.. :frowning:

Here is an example that I wrote to get data from Bluetooth to control a servo.
You send a packet with the syntax as < delayTime, servoPosition >. The sketch parses the packet and moves the servo from 90 degrees to the position in servoPosition then the servo pauses at that position for delayTime and returns to 90 degrees. Maybe you can adapt this to your needs. Note that my Bluetooth module is connected to Arduino pin 4 (RX to BT TX) and pin 7 (TX to BT RX) using software serial so I can use the hardware serial for upload and displaying the data received. Thanks again to Robin2 for the serial input basics thread.

So send, from the laptop, “<3000,170>” (without quotes) and the servo should move from 90 degrees to 170 degrees and pause for 3000 milliseconds then return to 90 degrees.

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

Servo servo;
SoftwareSerial bt(4, 7); // RX, TX

const byte numChars = 12;
char receivedChars[numChars];
char tempChars[numChars];        // temporary array for use when parsing

// variables to hold the parsed data
unsigned long delayTime;  // servo sweep delay time
int servoPosition = 0;    // servo position

boolean newData = false;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  bt.begin(9600);
  servo.write(90);
  servo.attach(2);
}

void loop()
{ // run over and over
  recvWithStartEndMarkers();
  if (newData == true)
  {
    strcpy(tempChars, receivedChars);
    // this temporary copy is necessary to protect the original data
    //   because strtok() used in parseData() replaces the commas with \0
    parseData();
    showParsedData();
    newData = false;

    servo.write(servoPosition);
    delay(delayTime);
    servo.write(90);    
  }
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (bt.available() > 0 && newData == false)
  {
    rc = bt.read();

    if (recvInProgress == true)
    {
      if (rc != endMarker)
      {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else
      {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) 
    {
      recvInProgress = true;
    }
  }
}

//============

void parseData()
{ // split the data into its parts

  char * strtokIndx; // this is used by strtok() as an index

  strtokIndx = strtok(tempChars, ",");     // get the first part - the delay
  delayTime = atol(strtokIndx);

  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  servoPosition = atoi(strtokIndx);
}

//============

void showParsedData()
{
  Serial.print("delay time ");
  Serial.println(delayTime);
  Serial.print("servo position ");
  Serial.println(servoPosition);
}

Thanks for your help! In the mean time, I wrote the next code:

#include <Servo.h> 
 
Servo myservo;  // create servo object to control a servo 
 
void setup() 
{ 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  Serial.begin(9600); //begins serial communication
} 
  
void loop() 
{ 
  int pos;
  if (Serial.available()){
    delay(100);
    while(Serial.available()>0){
      pos=Serial.read();     //reads the value sent from Visual Basic  
      if(pos=='0'){
      
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  } 
} 
    }
  } 
}

It works fine for me, however, it only makes 1 sweep. (so from 0 to 180 degrees and back) I want to make it an unlimited amount of sweeps. I think I made an error in the loops. Could someone help with that?

The second question is: I would like to make the angle of where it sweeps to adjustable. (so that I can change 180 to 40 degrees for example) I would like to do it on the Serial monitor. The other thing that I would like to change is the time of the delay. I would like to change that as well by giving a different input…

I really like your help by the way!!

So you want to adjust the start angle (0 now) and the finish angle (180 now) and specify the delay? And once started sweeps continuously? The changes made through the Serial port?

Here is a sketch that is a modification of the sketch in reply #5.

The syntax for this sketch is <delay time, start position, end position>.

#include <Servo.h>

Servo servo;

const byte numChars = 12;
char receivedChars[numChars];
char tempChars[numChars];        // temporary array for use when parsing

// variables to hold the parsed data
unsigned long delayTime = 15;  // servo sweep delay time
int servoStartPosition = 0;
int servoEndPosition = 180;    

boolean newData = false;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  servo.write(90);
  servo.attach(2);
}

void loop()
{ // run over and over
  recvWithStartEndMarkers();
  if (newData == true)
  {
    strcpy(tempChars, receivedChars);
    // this temporary copy is necessary to protect the original data
    //   because strtok() used in parseData() replaces the commas with \0
    parseData();
    showParsedData();
    newData = false;
  }
  servoSweep(delayTime, servoStartPosition, servoEndPosition);
}

void servoSweep(int delayT, int startPos, int endPos)
{
  for (int pos = startPos; pos <= endPos; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    servo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(delayT);                       // waits 15ms for the servo to reach the position
  }
  for (int pos = endPos; pos >= startPos; pos -= 1) { // goes from 180 degrees to 0 degrees
    servo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(delayT);                       // waits 15ms for the servo to reach the position
  } 
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (Serial.available() > 0 && newData == false)
  {
    rc = Serial.read();

    if (recvInProgress == true)
    {
      if (rc != endMarker)
      {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else
      {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker)
    {
      recvInProgress = true;
    }
  }
}

//============

void parseData()
{ // split the data into its parts

  char * strtokIndx; // this is used by strtok() as an index

  strtokIndx = strtok(tempChars, ",");     // get the first part - the delay
  delayTime = atol(strtokIndx);

  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  servoStartPosition = atoi(strtokIndx);
  strtokIndx = strtok(NULL, ",");
  servoEndPosition = atoi(strtokIndx);
}

//============

void showParsedData()
{
  Serial.print("delay time ");
  Serial.println(delayTime);
  Serial.print("servo starting position ");
  Serial.println(servoStartPosition);
  Serial.print("servo ending position ");
  Serial.println(servoEndPosition);  
}

Thank you very much!!