0

One of the requirements of my projects is to send data from my application to the Arduino robot.

I have windows 10, and my robot is Arduino Uno. The Bluetooth I'm using on my robot is HC-06.

The app side:

  • I'm writing some script (With the format I've created)
  • Then converting it into JsonString
  • Opening the port and sending a start communication signal.
  • Sending the JsonString, each represents another command and they're separated with a special character that can't be written in the script. Here's the problem, I tried sending string length of 256 bytes (not a JsonString) just to test the Bluetooth.

The test I did in my robot

  • I read the data
  • Turned the led on
  • Waited (data.length() / 10) seconds
  • Turned the led off

For my data of 256 bytes, the led was ON for 12.8 seconds, which is 128 bytes. And sometimes when I changed some stuff The time was 6.4 seconds.

C# (Application)

string data = @"0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101";

protocolBT.BTcontroller.OpenPort();                   
protocolBT.BTcontroller.SendChar(ProtocolBT.COM_OpenChar);
protocolBT.BTcontroller.SendBigData(data);
protocolBT.BTcontroller.ClosePort();

The Bluetooth Class

public class BluetoothController
{
    private readonly SerialPort _serialPort;


    public BluetoothController(string portName, BaudRate baudRate)
    {
        _serialPort = new SerialPort(portName, (int)baudRate, Parity.None, 8, StopBits.One);
    }

    public static bool IsBluetoothSupported()
    {
        return BluetoothRadio.IsSupported;
    }

    public static void SetConnection()
    {
        if (IsBluetoothSupported())
        {
            if (BluetoothRadio.PrimaryRadio.Mode == RadioMode.PowerOff)
                BluetoothRadio.PrimaryRadio.Mode = RadioMode.Connectable;
        }
    }


    public void OpenPort()
    {
        try
        {
            _serialPort.Open();
        }
        catch(IOException IOex)
        {
            throw IOex;
        }
    }

    public void ClosePort()
    {
        _serialPort.Close();
    }

    public void SendData(string msg)
    {
        try
        {
            if (_serialPort.IsOpen)
            {
                byte[] data = Encoding.UTF8.GetBytes(msg);
                _serialPort.Write(data, 0, data.Length);
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }


    public void SendBigData(string msg)
    {
        try
        {
            if (_serialPort.IsOpen)
            {
                foreach (char ch in msg)
                {
                    SendChar(ch);
                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    public void SendChar(char ch)
    {
        try
        {
            if (_serialPort.IsOpen)
            {
                byte[] data = Encoding.UTF8.GetBytes(new char[]{ ch });
                _serialPort.Write(data, 0, data.Length);
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

}

And this is my Arduino test code

#include <SoftwareSerial.h>

#define RX 10
#define TX 11
SoftwareSerial BT = SoftwareSerial(RX, TX);


String startCom = "»";

String MessageStart = "";
bool isListen = false;
String data = "";

int yellow = 12;



void setup() 
{
  // Define LED
  pinMode(yellow, OUTPUT);

  // Test yellow led
  digitalWrite(yellow, HIGH);
  delay(1000);
  digitalWrite(yellow, LOW);

  // Define Bluetooth
  pinMode(RX, INPUT);
  pinMode(TX, OUTPUT);
  BT.begin(9600);
}


void loop() 
{
  if(isListen == false)
  {
    readStartCommand();
  }
  else if(isListen == true)
  {
    readAllData();

    int len = data.length();
    if(len > 0)
    {
      robotLedOn(0); // Turn on the yellow led
      for(int i = 0; i < len; i++) // Wait (len * 0.1) second
      {
        delay(100);
      }
      robotLedOff(0); // Turn off the yelloe led
    }
  }
}


void readStartCommand()
{
  if(BT.available() > 0)
  {
    char ch = BT.read();
    Message += ch;

    if(MessageStart == startCom)
    {
      // Blink the yellow led if the start communication command recieved
      robotLedOn(0);
      delay(1000);
      robotLedOff(0);
      delay(2000);

      MessageStart = "";
      isListen = true;
    }
  }
}

void readAllData()
{

  while(BT.available() > 0)
  {
    data += BT.read();
  }
  isListen = false;
}

I tried to put the 256 bytes data manually to string in the Arduino and the timer was on 25.6 seconds. So I think that there is a limit for the size of the data that Bluetooth can handle.

Note:

  • I need Json because I have complicated commands, not only leds. Some of the commands require multi-parameters from different types.
  • Soon I will get Arduino-Mega because I don't have enough pins in my Uno.

Tried:

  • Change the timeout, it still stops receiving at 128 bytes. with read() and setTimeout(100-2000) Timer result: 12.8 seconds With readString() and setTimeout(100-2000) Timer result: 6.4 seconds

  • My WriteBufferSize in the PC Bluetooth is 2048 bytes. So I'm pretty sure that all the data is sent.

  • Different Baud Rates and using the Library instead of the The only change is that now the timer stops at 15.5 seconds...

  • Use BT.flush() and all my data is sent 100% for sure, the problem is in receiving in my Arduino. I think there is a buffer limit for the data...

  • Using another Bluetooth device, still the result is 15.5 seconds instead of 25.6 seconds.

  • why are using JSON? ..... why don't you simply use single byte commands with single byte data such as, for example L10 or L:1:0 which could mean LED 1 off ? – jsotola Dec 26 '18 at 20:45
  • 1
  • 1
    For any communication you have to indicate your packet end somehow. You can use termination character ot fixed data length. And you have to read data from serial port on Arduino side until receive the termination character ot reach the packet length. – Mike Petrichenko Dec 27 '18 at 4:02
  • timeout is not applied for available() and read() that is why your code stops reading at a gap in data flow. are the coming in until you blink the LED 3 seconds? then you loose data there – Juraj Jan 3 at 19:06
0

You stop reading at first gap between bytes. For simple case, you can use data = BT.readString(). It will wait for the next char. So at the end it will wait a second. If it is too long use BT.setTimeout(100) in setup().

Note: using String in small memory of Uno will cause memory fragmentation and crash

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.