Bluetooth-controlled Servos

Hi, I am new to Arduino and I am currently trying to build a project as a hobby. Please take no offense if my question(s) seem too ignorant/stupid and feel free to correct me. The codings are attached below.

Here is what happened:

My first attempt was to control two servo motors wirelessly using a Wii-Nunchuck controller through Bluetooth. I first tested the wired version with some code I found online and it worked:

https://create.arduino.cc/projecthub/mtashiro/control-servos-using-wii-nunchuk-9136bd

I used Arduino Nano instead of UNO, and had a WiiChuk Adapter (Saves the trouble of opening up the Nunchuck)

Next, I wanted to turn it wireless by using Bluetooth through SoftSerial, which ultimately, I hope to turn it into a Bluetooth-controlled car after clearing this step. With two HC-12 Bluetooth module (for each arduino), and throwing in another Arduino Nano, two sets of data (x & y) will be sent from the Wii Nunchuck controller side constantly to the Servo Side, and this is where I have a small problem due to my lack of programming skill.

First Problem: I am able to send both sets of data accurately and the servo side is able to receive them with no problem. The problem is that how do I assign each set of data to each servo? E.g. x>servoLeft and y>servoRight

This is what I have on the servo side for receiving the data from the Nunchuck side as I only know how to receive ALL the values sent from the Nunchuck side and not sort them accordingly. I had to disable the y_axis data on the nunchuck side and send only the x_axis data, hence allowing me to only control 1 servo due to this.

if (Wireless_Serial.available())
{
Serial.write(Wireless_Serial.read());
values = Serial.read();
servoLeft.write(x_axis);
}

Second Problem: Even with this, servoLeft should be able to controlled properly, however, the servo is just swinging back and forth rapidly on its own (about 30 degrees) and causes the motor to heat up. I am able to receive correct values for the x_axis, however, the servo just keeps swinging back and forth abruptly and I do not know what went wrong. I have read on of the article online that the SoftSerial library conflicts with the Servo library, is it possible that this is the reason for the servo's behaviour? I have also noticed that when I swing the nunchuck button left, the servo random swings are slower, and when i swing the button right, the random swings goes faster.

Wii Nunchuck controller side
x1 Arduino Nano connected with (Wii Nunchuck + Adapter) and 1 HC-12

Servo Side
x1 Arduino Nano connected with 2 servo motors and 1 HC-12

servo_side.ino (1.24 KB)

nunchuck_controller.ino (4.43 KB)

After more research online and I found some tutorials that uses Android to control multiple servo through Bluetooth
(Master: Android, Slave: HC-06), through hard serial.

I have tried the tutorial (link below) but it did not seem to work, despite being able to connect successfully (HC-06 not blinking too), the data doesn't seem to be sending properly from my phone (Galaxy Note 5) to the arduino, either that, or the Arduino is not receiving the data, as the data displayed on the Serial Monitor are not updated and constantly shows the same values.

I have also tried a few other similar tutorials and face the same problem for all of them, and I have not changed the codings (other than the pinout for the servos/HC-06).

Does anyone know the possible problems behind this? Or any other possible solution(s) to control multiple servos via Bluetooth? :confused:

If you want to get help effectively you need to focus on one option. It's just too confusing when you are asking questions about widely differing options.

When you have made a choice post the code you are using and tell us what it actually does and what you want it to do that is different.

...R
Planning and Implementing a Program

Hi,

Thanks for the feedback and I apologize for the confusion on my part, please ignore my first comment.

Basically, I will like to control two servo motors with a Wii Nunchuck controller, and I have a few questions regarding it:

  1. Two sets of data will be sent constantly from the Wii Nunchuck Side to the Servo Motor Side, let's call them x & y respectively. The x & y values are sent in without delay so they are in pretty large quantity. On the servo side, I only know how to display ALL the data that are being received. However, what I want to know is how to assign value x to Servo1 and value y to Servo2, before commanding the servos to execute the assigned values.

  2. While attempting to control one servo via the method mentioned above, the servo was just swinging back and forth randomly despite that the x values are being received on the servo side and executed properly. Hence I am not sure if the idea of using Bluetooth + SoftwareSerial along with Servo works and will like to clarify if the idea is viable as I have read somewhere that The SoftwareSerial and Servo libraries conflict with each other.

Wii Nunchuck Side Connections (Transmitter)

HC-12 > Arduino Nano
VCC > 5V
GND > GND
TX > D10
RX > D11

Wii Nunchuk Adapter > Arduino Nano

  • (GND) > GND
  • (VCC) > VCC
    d > A4
    c > A5

Servo Motor Side (Receiver)

Servo 1 & 2 > Arduino Nano
VCC > VCC
GND > GND
Servo1 output > D9
Servo2 output > D10

**HC-12 > Arduino Nano **
VCC > 5V
GND > GND
TX > D2
RX > D3

Wii Nunchuck Side Code[/b]
```
**[u]#include <Wire.h>
#include <SoftwareSerial.h>

SoftwareSerial Wireless_Serial (10,11);                //Rx | Tx

static uint8_t nunchuck_buf[6];  // array to store nunchuck data,

void setup()
{
  Serial.begin(9600);
  Wireless_Serial.begin(9600);
 
  nunchuck_setpowerpins(); // use analog pins 2&3 as fake gnd & pwr
  nunchuck_init(); // send the initilization handshake
  Serial.print ("Finished setup\n");
}

void loop()
{
  nunchuck_get_data();

// map nunchuk data to a servo data point
  int x_axis = map(nunchuck_buf[0], 23, 222, 180, 0);
  int y_axis = map(nunchuck_buf[1], 32, 231, 0, 180);

//move servo to desired position based on Wii nunchuk reading
Wireless_Serial.print(x_axis);
//Wireless_Serial.print(y_axis);
   
// un-comment next line to print data to serial monitor 
//  nunchuck_print_data();

if (Serial.available())
      {
      Wireless_Serial.write(Serial.read());
      }     
}

//
// Nunchuck functions
//

// Uses port C (analog in) pins as power & ground for Nunchuck
static void nunchuck_setpowerpins()
{
#define pwrpin PORTC3
#define gndpin PORTC2
    DDRC |= _BV(pwrpin) | _BV(gndpin);
    PORTC &=~ _BV(gndpin);
    PORTC |=  _BV(pwrpin);
    delay(100);  // wait for things to stabilize       
}

// initialize the I2C system, join the I2C bus,
// and tell the nunchuck we're talking to it
void nunchuck_init()
{
  Wire.begin();                      // join i2c bus as master
  Wire.beginTransmission(0x52);    // transmit to device 0x52
  Wire.write(0x40);            // sends memory address
  Wire.write(0x00);            // sends sent a zero. 
  Wire.endTransmission();    // stop transmitting
}

// Send a request for data to the nunchuck
// was "send_zero()"
void nunchuck_send_request()
{
  Wire.beginTransmission(0x52);    // transmit to device 0x52
  Wire.write(0x00);            // sends one byte
  Wire.endTransmission();    // stop transmitting
}

// Receive data back from the nunchuck,
int nunchuck_get_data()
{
    int cnt=0;
    Wire.requestFrom (0x52, 6);    // request data from nunchuck
    while (Wire.available ()) {
      // receive byte as an integer
      nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.read());
      cnt++;
    }
    nunchuck_send_request();  // send request for next data payload
    // If we recieved the 6 bytes, then go print them
    if (cnt >= 5) {
    return 1;  // success
    }
    return 0; //failure
}

// Print the input data we have recieved
// accel data is 10 bits long
// so we read 8 bits, then we have to add
// on the last 2 bits.  That is why I
// multiply them by 2 * 2
void nunchuck_print_data()
{
  static int i=0;
  int joy_x_axis = nunchuck_buf[0];
  int joy_y_axis = nunchuck_buf[1];

int accel_x_axis = nunchuck_buf[2]; // * 2 * 2;
  int accel_y_axis = nunchuck_buf[3]; // * 2 * 2;
  int accel_z_axis = nunchuck_buf[4]; // * 2 * 2;

int z_button = 0;
  int c_button = 0;

// byte nunchuck_buf[5] contains bits for z and c buttons
  // it also contains the least significant bits for the accelerometer data
  // so we have to check each bit of byte outbuf[5]
  if ((nunchuck_buf[5] >> 0) & 1)
    z_button = 1;
  if ((nunchuck_buf[5] >> 1) & 1)
    c_button = 1;

if ((nunchuck_buf[5] >> 2) & 1)
    accel_x_axis += 2;
  if ((nunchuck_buf[5] >> 3) & 1)
    accel_x_axis += 1;

if ((nunchuck_buf[5] >> 4) & 1)
    accel_y_axis += 2;
  if ((nunchuck_buf[5] >> 5) & 1)
    accel_y_axis += 1;

if ((nunchuck_buf[5] >> 6) & 1)
    accel_z_axis += 2;
  if ((nunchuck_buf[5] >> 7) & 1)
    accel_z_axis += 1;

Serial.print(i,DEC);
  Serial.print("\t");
 
  Serial.print("joy:");
  Serial.print(joy_x_axis,DEC);
  Serial.print(",");
  Serial.print(joy_y_axis, DEC);
  Serial.print("  \t");

Serial.print("acc:");
  Serial.print(accel_x_axis, DEC);
  Serial.print(",");
  Serial.print(accel_y_axis, DEC);
  Serial.print(",");
  Serial.print(accel_z_axis, DEC);
  Serial.print("\t");

Serial.print("but:");
  Serial.print(z_button, DEC);
  Serial.print(",");
  Serial.print(c_button, DEC);

Serial.print("\r\n");  // newline
  i++;
}

// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char nunchuk_decode_byte (char x)
{
  x = (x ^ 0x17) + 0x17;
  return x;
}[/u]**
[/u]** __[u]**[u]Servo Side Code[/b][/u]**[/u]__ __[u]**[u][/u]__
[u]**[u]//#include <Wire.h>
#include <Servo.h>
#include <SoftwareSerial.h>

Servo servoLeft;          // Define left servo
//Servo servoRight;        // Define right servo
SoftwareSerial Wireless_Serial (2,3);                //Rx | Tx

//static uint8_t nunchuck_buf[6];  // array to store nunchuck data,

void setup()
{
  Serial.begin(9600);
  Wireless_Serial.begin(9600);
 
  servoLeft.attach(10);  // Set left servo to digital pin 10
  //servoRight.attach(9);  // Set right servo to digital pin 9

}

void loop()
{
 
  if (Wireless_Serial.available())
      {
      Serial.write(Wireless_Serial.read());
      int values = Wireless_Serial.read();
      servoLeft.write(values);
      }

}[/u][/u]
__[u]
```**[/u]__

Have a look at the 3rd example (and the parse example) in Serial Input Basics

Send your data like this

Wireless_Serial.print('<');
Wireless_Serial.print(x_axis);
Wireless_Serial.print(',');   // comma
Wireless_Serial.print(y_axis);
Wireless_Serial.print('>');

I don't know what this code is for

  if (Serial.available())
      {
      Wireless_Serial.write(Serial.read());
      }

but I suspect it will just muck things up.

...R

I believe the parsing example you mentioned refers to example 5 in the given link. Forgive me but I do not understand how the recvWithStartEndMarkers(); function works as my programming skills are pretty basic. I only want two integers (x_axis and y_axis), however, in this example there is an addition messageFromPC along with numChars, and numChars appear in several parts of the coding so I am unsure of which part to delete or change to remove the messageFromPC.

I have edited your coding and below is what I have come up with, but I received a 'parseData was not declared in the scope error' but I could not find the problem regarding that issue, it is also likely that there are several other errors I have made.

At the moment, x_axis and y_axis data are being sent in from the transmitter side via Bluetooth HC-12 (SoftwareSerial). E.g <89,90>

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

Servo servoLeft;          // Define left servo
Servo servoRight;         // Define right servo
SoftwareSerial Wireless_Serial (2,3);                 //Rx | Tx


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

char messageFromPC[numChars] = {0};
int x_axis = 0;
int y_axis = 0;

boolean newData = false;

void setup()
{
  Serial.begin(9600);
  Wireless_Serial.begin(9600);
  
  servoLeft.attach(10);  // Set left servo to digital pin 10
  servoRight.attach(9);  // Set right servo to digital pin 9
 
}

void loop()
{
    if (newData == true) 
    {
        recvWithStartEndMarkers();
        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;
    }  
}


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

    while (Wireless_Serial.available() > 0 && newData == false) 
    {
        rc = Wireless_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 string
    strcpy(messageFromPC, strtokIndx);        // copy it to messageFromPC
 
    strtokIndx = strtok(NULL, ",");           // this continues where the previous call left off
    x_axis = atoi(strtokIndx);                // convert this part to an integer

    strtokIndx = strtok(NULL, ",");           // this continues where the previous call left off
    y_axis = atoi(strtokIndx);                // convert this part to an integer

}

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

void showParsedData() 
{
    servoLeft.write(x_axis);
    servoRight.write(y_axis);
    Serial.print("x_axis: "); Serial.println(x_axis);
    Serial.print("y_axis: "); Serial.println(y_axis);
}

Kikishiru:
I only want two integers (x_axis and y_axis), however, in this example there is an addition messageFromPC along with numChars, and numChars appear in several parts of the coding so I am unsure of which part to delete or change to remove the messageFromPC.

In the parse example you just need to pull two integers from the data rather than text, an integer and a floating point value.

From this

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 string
    strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
 
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ",");
    floatFromPC = atof(strtokIndx);     // convert this part to a float

}

to this (assuming the first value is the xValue)

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 string
    xValue = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    yValue = atoi(strtokIndx);     // convert this part to a float

}

I have not tested this change

...R

I have been trying to find out the problem causing the 'parseData was not declared in this scope' problem but to no avail. I have checked the entire code numerous times but as far as I know of, I couldn't find the formatting mistake causing it. I have faced similar problem earlier too but it was solved after I changed from a Leonardo board to a Nano but that does not seem to be the case for this. I also tried disconnecting the Arduino and only compile (verify) the coding and still receives the same error.

The code is as shown below:

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

Servo servoLeft;          // Define left servo
Servo servoRight;         // Define right servo
SoftwareSerial Wireless_Serial (2,3);                 //Rx | Tx


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

char messageFromPC[numChars] = {0}; 
int x_axis = 0;
int y_axis = 0;

boolean newData = false;

void setup()
{
  Serial.begin(9600);
  Wireless_Serial.begin(9600);
  
  servoLeft.attach(10);  // Set left servo to digital pin 10
  servoRight.attach(9);  // Set right servo to digital pin 9
}

void loop()
{
    if (newData == true) 
    {
        recvWithStartEndMarkers();
        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;
    }  
  /*
  // map nunchuk data to a servo data point
  //int x_axis = map(nunchuck_buf[0], 23, 222, 180, 0);
  //int y_axis = map(nunchuck_buf[1], 32, 231, 0, 180);
  
  if (Wireless_Serial.available())
      {
      Serial.write(Wireless_Serial.read());
      int values = Wireless_Serial.read();
      servoLeft.write(values);
      }
 
  if (Serial.available())
      {
      Wireless_Serial.print(Serial.read());
      //int values = Serial.read();
      //servoLeft.write(values);
      } 
   */ 
}


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

    while (Wireless_Serial.available() > 0 && newData == false) 
    {
        rc = Wireless_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 string
    x_axis = atoi(strtokIndx);               // convert this part to an integer

    strtokIndx = strtok(NULL, ",");          // this continues where the previous call left off
    y_axis = atoi(strtokIndx);               // convert this part to a float

}

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

void showParsedData() 
{
    servoLeft.write(x_axis);
    servoRight.write(y_axis);
    Serial.print("x_axis: "); Serial.println(x_axis);
    Serial.print("y_axis: "); Serial.println(y_axis);
}

Kikishiru:
I have been trying to find out the problem causing the 'parseData was not declared in this scope' problem but to no avail.

Delete */ at the start of line 100

...R

Wow, I have scrolled through it tens of times and I totally overlooked and missed the " * "... Thank you!!

I have tested the following code on the receiver (servo) side and the data are not being received at all. I suspect it is the recvWithStartEndMarkers function that I have edited wrongly but I do not know what went wrong as I do not understand the coding within that function.

I have tried removing the showParsedData function and there is no difference in the servos' movement, which probably means the data are not being received. I have tested the transmitter (nunchuck) side and they are all working fine. Nunchuck sending in proper readings and bluetooth module sending data properly too.

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

Servo servoLeft;          // Define left servo
Servo servoRight;         // Define right servo
SoftwareSerial Wireless_Serial (2,3);                 //Rx | Tx


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

char messageFromPC[numChars] = {0}; 
int x_axis = 0;
int y_axis = 0;

boolean newData = false;

void setup()
{
  Serial.begin(9600);
  Wireless_Serial.begin(9600);
  
  servoLeft.attach(10);  // Set left servo to digital pin 10
  servoRight.attach(9);  // Set right servo to digital pin 9
}

void loop()
{
    if (newData == true) 
    {
        recvWithStartEndMarkers();
        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;
    }  
  /*
  if (Wireless_Serial.available())
      {
      Serial.write(Wireless_Serial.read());
      int values = Wireless_Serial.read();
      servoLeft.write(values);
      }
 
  if (Serial.available())
      {
      Wireless_Serial.print(Serial.read());
      //int values = Serial.read();
      //servoLeft.write(values);
      } 
   */ 
}


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

    if (Wireless_Serial.available() > 0 && newData == false) 
    {
        rc = Wireless_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 string
    x_axis = atoi(strtokIndx);               // convert this part to an integer

    strtokIndx = strtok(NULL,",");           // this continues where the previous call left off
    y_axis = atoi(strtokIndx);               // convert this part to a float

}

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

void showParsedData() 
{
    servoLeft.write(x_axis);
    servoRight.write(y_axis);
    Serial.print("x_axis: "); Serial.println(x_axis);
    Serial.print("y_axis: "); Serial.println(y_axis);
}

Temporarily add these new lines into loop()

       recvWithStartEndMarkers();
        if (newData == true) {                              // NEW
            Serial.println(receivedChars);               // NEW
        }                                                            // NEW
        strcpy(tempChars, receivedChars);

so you can see if anything is being received.

If it is not then the problem may be in the data that is being sent.

...R

Like this? I am receiving values but they are all random values and not the values that are being sent from transmitter side.

void loop()
{
    recvWithStartEndMarkers();
    if (newData == true) 
    {
        Serial.println(receivedChars);
    }
        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; 
}

Post some samples of what you are receiving together with what it should be.

...R

The x and y values range from 0 to 180 depending on the nunchuck position. When at rest, both values should be close to 90. With only the receiver side powered up (without the transmitter side powering up), the values received are 0.

I have attached gifs of them.

"Actual sending" - Transmitter Nunchuck side (Intended values to be sent to servos)
(Unable to upload the sending gif due to the upload space limit on forum but the values are as mentioned above)

"Actual receiving" - Receiver Servo Side (What is being received)

Actual receiving.gif

Image from Reply #14 so we don't have to download it. See this Image Guide

Edit - I deleted the image because it is a moving GIF that is just irritating

...R

That is completely unreadable and just irritating,

Don't post text as pictures - especially moving pictures. Just copy and paste the text - for both sending and receiving.

...R

There are hundreds of data every few seconds so I figured a gif will be better, I am sorry that it was irritating. I have copied some data below, there are several different patterns of random data on the servo side but I just picked a few.

Sending data from Nunchuck Side
The values below reflects the respective position of the nunchuck:
(At rest/Middle position values)
x_axis: 92
y_axis: 85
x_axis: 92
y_axis: 85
x_axis: 92
y_axis: 85

(Left position values)
x_axis: 108
y_axis: 80
x_axis: 141
y_axis: 75
x_axis: 168
y_axis: 68

(Up position values)
x_axis: 104
y_axis: 104
x_axis: 104
y_axis: 104
x_axis: 102
y_axis: 105

(Right position values)
x_axis: 92
y_axis: 143
x_axis: 92
y_axis: 159
x_axis: 92
y_axis: 173
x_axis: 91
y_axis: 180

(Down position values)
x_axis: -2
y_axis: 94
x_axis: -1
y_axis: 95
x_axis: 0
y_axis: 97
x_axis: 0
y_axis: 97

Received data from Servo Side
x_axis: 10
y_axis: 5352
10<4507<<45<,5352<<6<<<<<
x_axis: 10
y_axis: 5352
x_axis: 186
y_axis: 0
186<<1<<19<--
x_axis: 186
y_axis: 0
x_axis: 0
y_axis: 0
<,<<9<<<<<4<<,<80<9040<4<8<8<6,
x_axis: 0
y_axis: 0
x_axis: 0
y_axis: 0
<8<<<
x_axis: 0
y_axis: 0
x_axis: 8
y_axis: 0
08<<897<8,<<8<<88<9<8<<8
x_axis: 8
y_axis: 0
x_axis: 9
y_axis: 0
x_axis: 9
y_axis: 0
x_axis: 98
y_axis: 0
x_axis: 98
y_axis: 0
x_axis: 98
y_axis: 0

What I have been hoping to see is something simple like ...

this data is sent "dffgdh" and this data is received "otjsjjs". One message sent, and one received, with several examples. That way it may be possible to see a pattern in the errors.

"There are hundreds of data every few seconds" suggests that you are sending data too quickly and the system is being overwhelmed. Slow the sender down temporarily so it just sends a message once per second.

...R

It is necessary for the data to be sent without delay so as to move the servos accordingly to the nunchuck's position, and hence the hundreds of them every few seconds. It does not really matter if I have moved the nunchuck, the data being received were only consistent for a few seconds before being changed to another set of random data, occasionally some correct data are being received (such as 10/5000). Corrupted data are being generated in the wrong format such as:

  1. 10<4507<<45<,5352<<6<<<<<
  2. <,<<9<<<<<4<<,<80<9040<4<8<8<6,
  3. 08<<897<8,<<8<<88<9<8<<8
  4. y_axis: 5352 (impossible value)

I have tried on another receiver with only the bluetooth and a simple code to receive the data and it works fine so it is not the bluetooth or transmitter problem. Some part of the coding on the servo side messed it up but I do not understand your example coding so I am unable to tell which part went wrong. It is also possible due to the SoftwareSerial and Servo libraries conflicting each other as I have read somewhere online.