Bluetooth Default Setting -

When running a Bluetooth module I’m now getting data back like:

“xx€ø€ø€xx€ø€øø”

The first couple of times I ran it, I was getting back normal data that I could read, but now it seems hooped so I suspect a setting is whacked somewhere, anyone have any suggestions? I’ve tried this with a Hydra and a Cerberus so I suspect the whacked setting is on the Bluetooth module. I am doing a Bluetooth.reset(); call, but I suspect this isn’t enough as it isn’t fixing the problem.

NOTE I haven’t connected to anything and if I do a bluetooth.HostMode.InquireDevice(); I get this bogus text string (or when I start the device I get it on a DataRevieved event).

Thanks

edit perhaps I should mention these are Bluetooth version 1.1 modules.

@ Duke Nukem -

You know a heck of a lot more about this than I do but I’ll reply anyway.

I have a version 1.1 module that is used to communicate with a Android device and I have had no problems with it.

I use the Bluetooth drive posted by Eduardo Velloso
https://gadgeteerbluetooth.codeplex.com/

I seem to recall (but not sure) that I had a issue when first using my Bluetooth.
I increased Sleep a bit for Reset…



            /// <summary>
            /// Hard Reset Bluetooth module
            /// </summary>
            public void Reset()
            {
                this.reset.Write(false);
                Thread.Sleep(5);
                this.reset.Write(true);
            }


Ignore if I’m offbase…

I’m definitely out-in-the-weeds when it comes with first-hand knowledge of the bluetooth module, but the most common problem I see in the forum in a mismatch in baud rate. For example see http://www.ghielectronics.com/community/forum/topic?id=11975&page=2

I initially thought the problem was baud rates as well however even if I do a DeviceInquired where all I do is dump the name and mac address to debug.print I get

So I’m think perhaps its more then baud rate.

When I run Eduardo’s sample (with 4.2 and with Hostmode) on startup I get:

Which again makes me wonder what is happening.

Are you using the driver I modified that has the ability to change the baud rate ? If so, it seems your module is set to a different baud rate than the port is set at. Can you connect the module to a PC via USB-UART connection and talk to it in different baud rates, so you can see what baud rate it’s set at? (yes, I honestly think this is baud rate mismatch :wink: )

What is the baud rate of an original module (ie where someone hasn’t messed it up)?

  1. Or 57600. Or 19200. Or 9600. Something like that :slight_smile:

According to http://www.seeedstudio.com/wiki/index.php?title=Serial_port_bluetooth_module_(Master/Slave) it’s 38400.

Looking over the module code in CodePlex I see:


        /// <summary></summary>
        /// <param name="socketNumber">The socket that this module is plugged in to.</param>
        /// <param name="baud">The baud rate to communicate with the module with.</param>
        public Bluetooth(int socketNumber, long baud)
        {
            // This finds the Socket instance from the user-specified socket number.  
            // This will generate user-friendly error messages if the socket is invalid.
            // If there is more than one socket on this module, then instead of "null" for the last parameter, 
            // put text that identifies the socket to the user (e.g. "S" if there is a socket type S)
            Socket socket = Socket.GetSocket(socketNumber, true, this, null);

            this.reset = new GTI.DigitalOutput(socket, Socket.Pin.Six, false, this);
            this.statusInt = new GTI.InterruptInput(socket, Socket.Pin.Three, GTI.GlitchFilterMode.Off, GTI.ResistorMode.Disabled, GTI.InterruptMode.RisingAndFallingEdge, this);
            this.serialPort = new GTI.Serial(socket, 38400, GTI.Serial.SerialParity.None, GTI.Serial.SerialStopBits.One, 8, GTI.Serial.HardwareFlowControl.NotRequired, this);

            //this.statusInt.Interrupt += new GTI.InterruptInput.InterruptEventHandler(statusInt_Interrupt);
            this.serialPort.ReadTimeout = Timeout.Infinite;
            this.serialPort.Open();

            Thread.Sleep(5);
            this.reset.Write(true);

            // Poundy added:
            Thread.Sleep(5);
            this.SetDeviceBaud(baud);
            this.serialPort.Flush();
            this.serialPort.Close();
            this.serialPort.BaudRate = (int)baud;
            this.serialPort.Open();
            // Poundy 

            readerThread = new Thread(new ThreadStart(runReaderThread));
            readerThread.Start();
            Thread.Sleep(500);
        }

So it looks like the baud rate is set, or can be set on initialization and by default is set to 38400 which is the supposed default. So yes it appears I’m using the latest/your driver.

Can someone try this code in their main when using a Bluetooth module that works so I can compare it to my values below?


        private void SerialPortSetup()
        {
            Debug.Print("AutoReadLineEnabled: " + bluetooth.serialPort.AutoReadLineEnabled.ToString());
            Debug.Print("BaudRate: " + bluetooth.serialPort.BaudRate.ToString());
            Debug.Print("DataBits: " + bluetooth.serialPort.DataBits.ToString());
            Debug.Print("Encoding: " + bluetooth.serialPort.Encoding.ToString());
            Debug.Print("IsOpen: " + bluetooth.serialPort.IsOpen.ToString());
            Debug.Print("LineReceivedEventDelimiter: " + bluetooth.serialPort.LineReceivedEventDelimiter.ToString());
            Debug.Print("Parity: " + bluetooth.serialPort.Parity.ToString());
            Debug.Print("PortName: " + bluetooth.serialPort.PortName.ToString());
            Debug.Print("ReadTimeout: " + bluetooth.serialPort.ReadTimeout.ToString());
            Debug.Print("StopBits: " + bluetooth.serialPort.StopBits.ToString());
            Debug.Print("UsingHardwareFlowControl: " + bluetooth.serialPort.UsingHardwareFlowControl.ToString());
            Debug.Print("WriteTimeout: " + bluetooth.serialPort.WriteTimeout.ToString());
        }

Thanks

Once the baud rate is set it continues to remain at that same setting even if you remove power. So be sure to always restart at the same baud rate.

I don’t have my BT module on me but I can’t remember seeing this… I was pretty sure the baud rate initialisation worked reliably when you had powered down the module. If you didn’t power it down, yes it stayed at the altered baud rate and the reinitialisation may be problematic. (the general behaviour of the driver, as you can see, is to open it at 38400 and then tell the module to connect at a new speed, then re-init the port at the new speed to match the module)

@ Duke did you connect it up to the universal UART diagnostics tool (the $3 USB-UART device)?

Hi Duke Nukem,
I`m working on this issue for some days and I have a working solution. It is not ready, some work and testing has still to be done but the modified bluetooth class sets the baudrate to the wanted value, independent of what the baudrate was before.

Edit: June 02, 2013 Changed the code to the latest Version
Edit: June 27 Info: Works only on spider. On Cerbuino the Messages form the BT- module come in chunks, which seems to be the reason that it does not work on this Mainboard.


// This is a Gadgeteer driver for the GHI Bluetooth Module NET. Microframework Vers. 4.2
// the original driver is from Eduardo Velloso -https://gadgeteerbluetooth.codeplex.com/
// Modification to set the baudrate of the Bluetooth module were made by 
// Brett Pound -https://gadgeteerbluetooth.codeplex.com/discussions/357827
// This modification by Roland Schmidt is intended to improve the setting of the baudrate of the Bluetooth Module

using System;
using Microsoft.SPOT;
using System.Threading;
using System.Text;

using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using GTI = Gadgeteer.Interfaces;

namespace Gadgeteer.Modules.Velloso
{
    /// <summary>
    /// A Bluetooth module for Microsoft .NET Gadgeteer
    /// </summary>
    public class Bluetooth : GTM.Module
    {

            /// <summary>
            /// Direct access to Serial Port.
            /// </summary>
            // Note by RoSchmi: Reference Gadgeteer.Serial must be added
            public GTI.Serial serialPort;
            private GTI.DigitalOutput reset;
            private GTI.InterruptInput statusInt;
            private Thread readerThread;
            
            //Added by RoSchmi
            private bool readerThread_isRunning = false;

            static public AutoResetEvent Wait_For_Baudrates_Match;

           // We take the possible baudrates two times in the array to try each baudrate two times to test for matching
            long[] possibleBaudrates = new long[16] { 0, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 
                                                      0, 9600, 19200, 38400, 57600, 115200, 230400, 460800};
            //End Added by RoSchmi

        /// <summary>
        /// Possible states of the Bluetooth module
        /// </summary>
            public enum BluetoothState
            {
                /// <summary>
                /// Module is initializing
                /// </summary>
                Initializing = 0,
                /// <summary>
                /// Module is ready
                /// </summary>
                Ready = 1,
                /// <summary>
                /// Module is in pairing mode
                /// </summary>
                Inquiring = 2,
                /// <summary>
                /// Module is making a connection attempt
                /// </summary>
                Connecting = 3,
                /// <summary>
                /// Module is connected
                /// </summary>
                Connected = 4,
                /// <summary>
                /// Module is diconnected
                /// </summary>
                Disconnected = 5
            }

            //Constructors changed by RoSchmi

            // Note: A constructor summary is auto-generated by the doc builder.
            /// <summary></summary>
            /// <param name="socketNumber">The socket that this module is plugged in to.</param>
            public Bluetooth(int socketNumber)
            {
                Complete_Common_Constructor(socketNumber, 38400);
            }

            // Note: A constructor summary is auto-generated by the doc builder.
            /// <summary></summary>
            /// <param name="socketNumber">The socket that this module is plugged in to.</param>
            /// <param name="baud">The baud rate to communicate with the module with.</param>
            public Bluetooth(int socketNumber, long baud)
            {
                // Throw an exception if a not allowed baudrate is passed as argument
                int pos = Array.IndexOf(possibleBaudrates, baud);
                if (!(pos >- 1)|(baud == 0))
                {
                    throw new System.ArgumentException("Argument of parameter baud (baudrate) not allowed. "
                                              + "Use 9600, 19200, 38400, 57600, 115200, 230400 or 460800");
                }
                Complete_Common_Constructor(socketNumber, baud);
            }

            private void Complete_Common_Constructor(int socketNumber, long baud)    // Common part of constructor
            {
                Thread.Sleep(1000);

                // This finds the Socket instance from the user-specified socket number.  
                // This will generate user-friendly error messages if the socket is invalid.
                // If there is more than one socket on this module, then instead of "null" for the last parameter, 
                // put text that identifies the socket to the user (e.g. "S" if there is a socket type S)
                Socket socket = Socket.GetSocket(socketNumber, true, this, null);

                this.reset = new GTI.DigitalOutput(socket, Socket.Pin.Six, false, this);
                this.statusInt = new GTI.InterruptInput(socket, Socket.Pin.Three, GTI.GlitchFilterMode.Off, GTI.ResistorMode.Disabled, GTI.InterruptMode.RisingAndFallingEdge, this);
                
                this.serialPort = new GTI.Serial(socket, (int)baud, GTI.Serial.SerialParity.None, GTI.Serial.SerialStopBits.One, 8, GTI.Serial.HardwareFlowControl.NotRequired, this);
                //this.statusInt.Interrupt += new GTI.InterruptInput.InterruptEventHandler(statusInt_Interrupt);
                this.serialPort.ReadTimeout = Timeout.Infinite;
                this.serialPort.Open();

                Debug.Print("Message from Class Bluetooth: Set up serialPort with baudrate: " + baud.ToString());
                
                Thread.Sleep(5);

                this.reset.Write(true);

               // Tests revealed that at least 470 msec are needed
               // Thread.Sleep(600);
                Thread.Sleep(600);

                possibleBaudrates[0] = baud;   // try first to connect with baudrate passed to the constructor as argument
                                               // if not successful with this baudrate, we try all possible baudrates two times
                possibleBaudrates[8] = baud;   // preset for the second run

                Wait_For_Baudrates_Match = new AutoResetEvent(false);

                for (int i = 0; i < possibleBaudrates.Length; i++)
                {
                    if (possibleBaudrates[i] != baud)  // if baudrate of serialPort is not already
                    {                                  // set to the new value, set baudrate of serialPort
                        this.serialPort.Flush();       // to new value
                        this.serialPort.Close();
                        Debug.Print("Message from Class Bluetooth: Set serialPort baudrate to: " + possibleBaudrates[i].ToString());
                        this.serialPort.BaudRate = (int)possibleBaudrates[i];
                        this.serialPort.Open();
                    }
                    Debug.Print("Message from Class Bluetooth: Try to set BT-Module baudrate to: " + possibleBaudrates[i].ToString());
                    this.SetDeviceBaud(possibleBaudrates[i]);  // try to set baudrate of BT-Module on this baudrate
                                                               // if we have the baudrate to which the
                                                               // BT-Module is actually set we will get
                                                               // "OK" or "ERROR" and the bautrate is set to the new
                                                               // value, otherwise we get not readable signs and the
                                                               // new bautrate will not be set

                    if (!readerThread_isRunning)  // if readerThread is not running, start new readerThread

                    {
                        readerThread = new Thread(new ThreadStart(runReaderThread));
                        readerThread.Start();
                        readerThread_isRunning = true;
                        Thread.Sleep(500);
                    }
                    
                    if (Wait_For_Baudrates_Match.WaitOne(50,false)) // Wait for matching bautrates
                    {
                         Debug.Print("Message from Class Bluetooth: Could connect to BT-Module with baudrate " + possibleBaudrates[i].ToString());
                         if (possibleBaudrates[i] != baud)
                         {
                             Debug.Print("Message from Class Bluetooth: Set BT-Device_Baudrate to baudrate passed as argument: " + baud.ToString());
                             this.SetDeviceBaud(baud);   // Set BT-Module to baudrate passed as argument
                             this.serialPort.Flush();
                             this.serialPort.Close();
                             Debug.Print("Message from Class Bluetooth: Set serialPort to baudrate passed as argument: " + baud.ToString());
                             this.serialPort.BaudRate = (int)baud;
                             this.serialPort.Open();
                         }
                        break;
                    }
                    else
                    {
                        Debug.Print("Message from Class Bluetooth: Could not connect to BT-Module with baudrate " + possibleBaudrates[i].ToString());
                    }
                }
               
            }

            /// <summary>
            /// Hard Reset Bluetooth module
            /// </summary>
            public void Reset()
            {
                this.reset.Write(false);
                Thread.Sleep(5);
                this.reset.Write(true);
            }

            /// <summary>
            /// Gets a value that indicates whether the bluetooth connection is connected.
            /// </summary>
            public bool IsConnected
            {
                get
                {
                    return this.statusInt.Read();
                }
            }

         
        // Reader Thread changed by RoSchmi

        /// <summary>
        /// Thread that continuously reads incoming messages from the module,
        /// parses them and triggers the corresponding events.
        /// </summary>
            private void runReaderThread()
            {
                Debug.Print("Message from Class Bluetooth, Reader Thread: Started");
                while (true)
                {
                   String response = "";
                   while (serialPort.BytesToRead > 0)
                   {
                       response = response + (char)serialPort.ReadByte();
                   }
                   if (response.Length > 0)
                   {
                       //Debug.Print("In reader thread arrived: " + response);

                       //Check Bluetooth State Changed
                       if (response.IndexOf("+BTSTATE:") > -1)
                       {
                           string atCommand = "+BTSTATE:";

                           //String parsing  
                           // Return format: +COPS:<mode>[,<format>,<oper>]
                           int first = response.IndexOf(atCommand) + atCommand.Length;
                           int last = response.IndexOf("\n", first);

                           // Changed by RoSchmi
                           int state = 0;
                           try
                           {
                               state = int.Parse(((response.Substring(first, last - first)).Trim()));
                           }
                           catch
                           {
                               Debug.Print("Error message: "+ response);
                           }
                           // End Changed by RoSchmi

                           OnBluetoothStateChanged(this, (BluetoothState)state);
                       }
                       //Check Pin Requested
                       if (response.IndexOf("+INPIN") > -1)
                       {
                           // EDUARDO : Needs testing
                           OnPinRequested(this);
                       }
                       if (response.IndexOf("+RTINQ") > -1)
                       {
                           //EDUARDO: Needs testing

                           string atCommand = "+RTINQ=";
                           //String parsing  
                           int first = response.IndexOf(atCommand) + atCommand.Length;
                           int mid = response.IndexOf(";", first);
                           int last = response.IndexOf("\r", first);
                           
                           // Keep reading until the end of the message
                           while (last < 0)
                           {
                               while (serialPort.BytesToRead > 0)
                               {
                                   response = response + (char)serialPort.ReadByte();
                               }
                               last = response.IndexOf("\r", first);
                           }

                           string address = ((response.Substring(first, mid - first)).Trim());
                           
                           string name = (response.Substring(mid+1, last-mid));

                           OnDeviceInquired(this, address, name);
                           //Debug.Print("Add: " + address + ", Name: " + name );
                       }
                       // Added by RoSchim
                       //Debug.Print("Message from Class Bluetooth, Reader Thread: Arrived at OK or ERROR parsing: " + response);
                       if ((response.IndexOf("OK") > -1) | (response.IndexOf("ERROR") > -1))
                       {
                           //Debug.Print("Message from Class Bluetooth, Reader Thread: Wait_For_Baudrates_Match Set (Released)");
                           Wait_For_Baudrates_Match.Set();
                           OnDataReceived(this, response);
                       }
                       else
                       {
                           OnDataReceived(this, response);
                       }
                       //End Added by RoSchmi
                   }
                   Thread.Sleep(1);  //poundy changed from thread.sleep(10)
                }
            }

            #region DELEGATES AND EVENTS
            #region Bluetooth State Changed
            /// <summary>
            /// Represents the delegate used for the <see cref="BluetoothStateChanged"/> event.
            /// </summary>
            /// <param name="sender">The object that raised the event.</param>
            /// <param name="btState">Current state of the Bluetooth module</param>
            public delegate void BluetoothStateChangedHandler(Bluetooth sender, BluetoothState btState);
            /// <summary>
            /// Event raised when the bluetooth module changes its state.
            /// </summary>
            public event BluetoothStateChangedHandler BluetoothStateChanged;
            private BluetoothStateChangedHandler onBluetoothStateChanged;

            /// <summary>
            /// Raises the <see cref="BluetoothStateChanged"/> event.
            /// </summary>
            /// <param name="sender">The object that raised the event.</param>  
            /// <param name="btState">Current state of the Bluetooth module</param>
            protected virtual void OnBluetoothStateChanged(Bluetooth sender, BluetoothState btState)
            {
                if (onBluetoothStateChanged == null) onBluetoothStateChanged = new BluetoothStateChangedHandler(OnBluetoothStateChanged);
                if (Program.CheckAndInvoke(BluetoothStateChanged, onBluetoothStateChanged, sender, btState))
                {
                    BluetoothStateChanged(sender, btState);
                }
            }
            #endregion
            
            #region DataReceived
            /// <summary>
            /// Represents the delegate used for the <see cref="DataReceived"/> event.
            /// </summary>
            /// <param name="sender">The object that raised the event.</param>
            /// <param name="data">Data received from the Bluetooth module</param>
            public delegate void DataReceivedHandler(Bluetooth sender, string data);
            /// <summary>
            /// Event raised when the bluetooth module changes its state.
            /// </summary>
            public event DataReceivedHandler DataReceived;
            private DataReceivedHandler onDataReceived;

            /// <summary>
            /// Raises the <see cref="DataReceived"/> event.
            /// </summary>
            /// <param name="sender">The object that raised the event.</param>  
            /// <param name="data">Data string received by the Bluetooth module</param>
            protected virtual void OnDataReceived(Bluetooth sender, string data)
            {
                if (onDataReceived == null) onDataReceived = new DataReceivedHandler(OnDataReceived);
                if (Program.CheckAndInvoke(DataReceived, onDataReceived, sender, data))
                {
                    DataReceived(sender, data);
                }
            }
            #endregion
            #region PinRequested
            /// <summary>
            /// Represents the delegate used for the <see cref="PinRequested"/> event.
            /// </summary>
            /// <param name="sender">The object that raised the event.</param>
            public delegate void PinRequestedHandler(Bluetooth sender);
            /// <summary>
            /// Event raised when the bluetooth module changes its state.
            /// </summary>
            public event PinRequestedHandler PinRequested;
            private PinRequestedHandler onPinRequested;

            /// <summary>
            /// Raises the <see cref="PinRequested"/> event.
            /// </summary>
            /// <param name="sender">The object that raised the event.</param>  
            protected virtual void OnPinRequested(Bluetooth sender)
            {
                if (onPinRequested == null) onPinRequested = new PinRequestedHandler(OnPinRequested);
                if (Program.CheckAndInvoke(PinRequested, onPinRequested, sender))
                {
                    PinRequested(sender);
                }
            }
            #endregion
            #endregion

            #region DeviceInquired
            /// <summary>
            /// Represents the delegate used for the <see cref="DeviceInquired"/> event.
            /// </summary>
            /// <param name="sender">The object that raised the event.</param>
            /// <param name="macAddress">MAC Address of the inquired device</param>
            /// <param name="name">Name of the inquired device</param>
            public delegate void DeviceInquiredHandler(Bluetooth sender, string macAddress, string name);
            /// <summary>
            /// Event raised when the bluetooth module changes its state.
            /// </summary>
            public event DeviceInquiredHandler DeviceInquired;
            private DeviceInquiredHandler onDeviceInquired;

            /// <summary>
            /// Raises the <see cref="PinRequested"/> event.
            /// </summary>
            /// <param name="sender">The object that raised the event.</param>  
            /// <param name="macAddress">MAC Address of the inquired device</param>
            /// <param name="name">Name of the inquired device</param>
            protected virtual void OnDeviceInquired(Bluetooth sender, string macAddress, string name)
            {
                if (onDeviceInquired == null) onDeviceInquired = new DeviceInquiredHandler(OnDeviceInquired);
                if (Program.CheckAndInvoke(DeviceInquired, onDeviceInquired, sender, macAddress, name))
                {
                    DeviceInquired(sender, macAddress, name);
                }
            }
            #endregion
            private object _lock = new Object();

            private Client _client;
        /// <summary>
        /// Sets Bluetooth module to work in Client mode.
        /// </summary>
            public Client ClientMode
            {
                get
                {
                    lock (_lock)
                    {
                        if (_host != null) throw new InvalidOperationException("Cannot use both Client and Host modes for Bluetooth module");
                        if (_client == null) _client = new Client(this);
                        return _client;
                    }
                }
            }

            private Host _host;
        /// <summary>
        /// Sets Bluetooth module to work in Host mode.
        /// </summary>
            public Host HostMode
            {
                get
                {
                    lock (_lock)
                    {
                        if (_client != null) throw new InvalidOperationException("Cannot use both Client and Host modes for Bluetooth module");
                        if (_host == null) _host = new Host(this);
                        return _host;
                    }
                }
            }

        /// <summary>
        /// Sets the device name as seen by other devices
        /// </summary>
        /// <param name="name">Name of the device</param>
            public void SetDeviceName(string name)
            {
                this.serialPort.Write("\r\n+STNA=" + name + "\r\n");
            }

            /// <summary>
            /// Switch the device to the directed speed
            /// </summary>
            /// <param baud="number">Name of the device</param>
            public void SetDeviceBaud(long baud)
            {
                
                string cmd = "";
                
                switch (baud)
                {
                    case 9600: 
                        cmd = "9600";
                        break;
                    case 19200:
                        cmd = "19200";
                        break;
                    case 38400:
                        cmd = "38400";
                        break;
                    case 57600:
                        cmd = "57600";
                        break;
                    case 115200:
                        cmd = "115200";
                        break;
                    case 230400:
                        cmd="230400";
                        break;
                    case 460800:
                        cmd="460800";
                        break;
                    default:
                        cmd="";
                        break;
                }
                
                if (cmd != "")
                    this.serialPort.Write("\r\n+STBD=" + cmd + "\r\n");

                //Thread.Sleep(1000);

                //todo: check it is working?! Probably should check the return code and do something about it. in the meantime,
                Thread.Sleep(500);
            }
          
            /// <summary>
            /// Sets the PIN code for the Bluetooth module
            /// </summary>
            /// <param name="pinCode"></param>
            public void SetPinCode(string pinCode)
            {
                this.serialPort.Write("\r\n+STPIN=" + pinCode +"\r\n");
            }


            // Added by RoSchmi

            /// <summary>
            /// Permit Auto-connect 
            /// </summary>
            public void PermitAutoConnect()
            {
                Debug.Print("Message from Class Buetooth: Permit auto-connect");
                this.serialPort.Write("\r\n+STAUTO=1\r\n");
            }
            /// <summary>
            /// Auto-connect forbidden
            /// </summary>
            public void DisableAutoConnect()
            {
                Debug.Print("Message from Class Buetooth: Disable auto-connect");
                this.serialPort.Write("\r\n+STAUTO=0\r\n");
            }
            /// <summary>
            /// Permit paired device to connect me
            /// </summary>
            public void PermitBeConnected()
            {
                Debug.Print("Message from Class Bluetooth: Permit be connected");
                this.serialPort.Write("\r\n+STOAUT=1\r\n");

            }
            /// <summary>
            /// Do not permit paired device to connect me
            /// </summary>
            public void DisableBeConnected()
            {
                Debug.Print("Message from Class Bluetooth: Disable be connected");
                this.serialPort.Write("\r\n+STOAUT=0\r\n");

            }

            /// <summary>
            /// Permit Auto-reconnect after getting out of range
            /// </summary>
            public void PermitAutoReconnect_LostConnection()
            {
                // Needs to be tested
                Debug.Print("Message from Class Bluetooth: Permit AutoReconnect after getting out of range");
                this.serialPort.Write("\r\n+LOSSRECONN=1\r\n");
            }

            /// <summary>
            /// Do not permit Auto-reconnect after getting out of range
            /// </summary>
            public void DisableAutoReconnect_LostConnection()
            {
                // Needs to be tested
                Debug.Print("Message from Class Bluetooth: Disable AutoReconnect after getting out of range");
                this.serialPort.Write("\r\n+LOSSRECONN=0\r\n");
            }

            /// <summary>
            /// Disable ECHO
            /// </summary>
            public void DisableECHO()
            {
                Debug.Print("Disable ECHO");
                this.serialPort.Write("\r\n+STECHO=0\r\n");
            }

            /// <summary>
            /// Enable ECHO
            /// </summary>
            public void EnableECHO()
            {
                Debug.Print("Enable ECHO");
                this.serialPort.Write("\r\n+STECHO=1\r\n");
            }

            // End added by RoSchmi




        /// <summary>
        /// Client functionality for the Bluetooth module
        /// </summary>
            public class Client
            {
                private Bluetooth bluetooth;
                internal Client(Bluetooth bluetooth)
                {
                    Debug.Print("Client Mode");
                    this.bluetooth = bluetooth;
                    bluetooth.serialPort.Write("\r\n+STWMOD=0\r\n");
                }

                /// <summary>
                /// Enters pairing mode
                /// </summary>
                public void EnterPairingMode()
                {
                    Debug.Print("Enter Pairing Mode");
                    bluetooth.serialPort.Write("\r\n+INQ=1\r\n");

                }

                /// <summary>
                /// Inputs pin code
                /// </summary>
                /// <param name="pinCode">Module's pin code. Default: 0000</param>
                public void InputPinCode(string pinCode)
                {
                    Debug.Print("Inputting pin: " + pinCode);
                    bluetooth.serialPort.Write("\r\n+RTPIN=" + pinCode + "\r\n");
                }

                /// <summary>
                /// Closes current connection. Doesn't work yet.
                /// </summary>
                public void Disconnect()
                {
                    Debug.Print("Disconnection is not working...");
                    //NOT WORKING
                    // Documentation states that in order to disconnect, we pull PIO0 HIGH,
                    // but this pin is not available in the socket... (see schematics)
                }

                /// <summary>
                /// Sends data through the connection.
                /// </summary>
                /// <param name="message">String containing the data to be sent</param>
                public void Send(string message)
                {
                    //Debug.Print("Sending string via bluetooth: .........");
                    bluetooth.serialPort.Write(message);
                    
                }

                //Added by RoSchmi

                /// <summary>
                /// Sends data through the connection.
                /// </summary>
                /// <param name="byteArray">Byte Array containing the data to be sent</param>
                ///
                public void Send(byte[] byteArray)
                {
                    //Debug.Print("Sending byteArray via bluetooth: .........");
                    bluetooth.serialPort.Write(byteArray);
                }
                // End Added by RoSchmi

                /// <summary>
                /// Sends data through the connection.
                /// </summary>
                /// <param name="message">String containing the data to be sent</param>
                ///
                public void SendLine(string message)
                {
                    Debug.Print("Sending: " + message);
                    bluetooth.serialPort.WriteLine(message);
                }
            }

        /// <summary>
        /// Implements the host functionality for the Bluetooth module
        /// </summary>
            public class Host
            {
                private Bluetooth bluetooth;
                internal Host(Bluetooth bluetooth)
                {
                    Debug.Print("Host mode");
                    this.bluetooth = bluetooth;
                    bluetooth.serialPort.Write("\r\n+STWMOD=1\r\n");
                }
                
                /// <summary>
                /// Starts inquiring for devices
                /// </summary>
                public void InquireDevice()
                {
                    Debug.Print("Inquiring device");
                    bluetooth.serialPort.Write("\r\n+INQ=1\r\n");
                    
                }

                /// <summary>
                /// Makes a connection with a device using its MAC address.
                /// </summary>
                /// <param name="macAddress">MAC address of the device</param>
                public void Connect(string macAddress)
                {
                    Debug.Print("Connecting to: " + macAddress);
                    bluetooth.serialPort.Write("\r\n+CONN="+macAddress+"\r\n");
                }

                /// <summary>
                /// Inputs the PIN code.
                /// </summary>
                /// <param name="pinCode">PIN code. Default 0000</param>
                public void InputPinCode(string pinCode)
                {
                    Debug.Print("Inputting pin: " + pinCode);
                    bluetooth.serialPort.Write("\r\n+RTPIN=" + pinCode + "\r\n");
                }

                /// <summary>
                /// Closes the current connection. Doesn't work yet.
                /// </summary>
                public void Disconnect()
                {
                    Debug.Print("Disconnection is not working...");
                    //NOT WORKING
                    // Documentation states that in order to disconnect, we pull PIO0 HIGH,
                    // but this pin is not available in the socket... (see schematics)
                }
            }
        }
    }



1 Like

And this is an application that uses the class (Spider, Bluetooth module on port 8, button on 11). The initialization is here done in a timer event (only to test, it’s not a good solution, but it works)

Edit: June 02, 2013 Changed the code to the latest version, initialization is now done
in “ProgramStarted”


using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;

using Gadgeteer.Modules.GHIElectronics;

using Gadgeteer.Modules.Velloso;

namespace Bluetooth_Pairing_Test
{
    public partial class Program
    {
            //*****************  Parameter to be changed by users  ***************************
            
            const string MyDeviceName = "MySpider";          // Device Name
            const string MyPinCode = "0000";                 // Pin Code
            const int MySocketNumber = 8;                    // The SocketNumber of the mainboard to which the BT-Module is connected
            const long BT_Device_Baudrate = 38400;           // Baudrate
            // possible baudrates 9600, 19200, 38400, 57600, 115200, 230400, 460800

            const int SendInterval = 1000;          // In this time interval  we send a message to the BT-Module



            //**************** End Parameter to be changed by user ***************************

            static private Bluetooth bluetooth;
            static private Bluetooth.Client client;

            static int MessageCounter = 0;    // Counter to count the sent messages
            
            // timerSendData is used to fire in interval to send data to the BT-Module
            GT.Timer timerSendData;
          
            // This method is run when the mainboard is powered up or reset.   
            void ProgramStarted()
            {
                // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
                Debug.Print("Program Started");

                // Event handler for button to enter pairing mode
                button.ButtonPressed += new Button.ButtonEventHandler(button_ButtonPressed);

                // Set a timer to send data to the BT-Module in intervals
                timerSendData = new GT.Timer(SendInterval);
                timerSendData.Tick += new GT.Timer.TickEventHandler(timerSendData_Tick);
                timerSendData.Stop();


                // define a bluetooth module running on socket: "MySocketNumber", baudrate: "BT_Device_Baudrate"
                Debug.Print("Program Message: Initialize Bluetooth module on Port " + MySocketNumber.ToString() 
                             + " Baudrate: " + BT_Device_Baudrate.ToString());
                
                bluetooth = new Bluetooth(MySocketNumber, BT_Device_Baudrate);

                Thread.Sleep(1000);

                // Set up eventhandler for state changes and data recieved.
                bluetooth.BluetoothStateChanged += new Bluetooth.BluetoothStateChangedHandler(bluetooth_BluetoothStateChanged);
                bluetooth.DataReceived += new Bluetooth.DataReceivedHandler(bluetooth_DataReceived);

                Debug.Print("Program Message: Set Bluetooth module to Client Mode" + "\r\n");
                client = bluetooth.ClientMode;
                Thread.Sleep(200);

                Debug.Print("Program Message: Set Device Name: " + MyDeviceName + "\r\n");
                bluetooth.SetDeviceName(MyDeviceName);
                Thread.Sleep(2000);

                Debug.Print("Program Message: Set Device Pincode" + "\r\n");
                bluetooth.SetPinCode(MyPinCode);
                Thread.Sleep(2000);
                /*
                Debug.Print("Program Message: Set BT-Device to: Disable Auto-connect " + "\r\n");
                bluetooth.DisableAutoConnect();
                Thread.Sleep(200);
                */
                
                Debug.Print("Program Message: Set BT-Device to: Enable Auto-connect " + "\r\n");
                bluetooth.PermitAutoConnect();
                Thread.Sleep(200);
                
                Debug.Print("Program Message: Set BT-Device to: PermitBeConnected" + "\r\n");
                bluetooth.PermitBeConnected();
                Thread.Sleep(200);

                bluetooth.serialPort.DiscardInBuffer();
                bluetooth.serialPort.DiscardOutBuffer();
                Thread.Sleep(200);

              //  client.EnterPairingMode();
              //  Thread.Sleep(3000);

                timerSendData.Start();
            }

            void timerSendData_Tick(GT.Timer timer)
            {
                Debug.Print("Program Message: ____________________________timerSendData ticked");
                // check to see that the bluetooth module is connected, and if so send a message over the connection
                if (bluetooth.IsConnected)
                {
                    Debug.Print("Program Message: BT is connected, so I send the message: " + "Hello from TinyClr, Message No.: " + MessageCounter.ToString());

                    client.Send("Hello from TinyClr, Message No.: " + MessageCounter.ToString() + "\r\n");
                    MessageCounter++;
                }
                else
                {
                    Debug.Print("Program message: BT is not connected, cannot send message");
                }
              
            }

            void button_ButtonPressed(Button sender, Button.ButtonState state)
            {
                // check to see that the bluetooth module is connected, and if so do nothing
                if (bluetooth.IsConnected)
                {
                    Debug.Print("Program Message: You pressed the button but BT was connected, so not activating pairing mode");
                }
                // otherwise, just go into first-time pairing mode.
                else
                {
                    Debug.Print("Program Message: You pressed the button and BT was not connected, so I go to pairing mode");
                    client.EnterPairingMode();
                }
            }

            private void bluetooth_DataReceived(Bluetooth sender, string data)
            {
                // For sample purposes, we'll just debug print what we get
                byte[] ReceivedBytes = new byte[data.Length];
                ReceivedBytes =  System.Text.UTF8Encoding.UTF8.GetBytes(data);
                Debug.Print("Program Message: Received Data from connected BT-Device. Byte-Count: " + data.Length.ToString() + " " + data);
            }

            void bluetooth_BluetoothStateChanged(Bluetooth sender, Bluetooth.BluetoothState btState)
            {
                // here the bluetooth module's state has changed. First, just debug print the value so we know what is happening
                Debug.Print("New state:" + btState.ToString());

                // If the state is now "connected", we can do stuff over the link.
                if (btState == Bluetooth.BluetoothState.Connected)
                {
                    Debug.Print("Program Message: BT-Connection established");
                    Thread.Sleep(900);      // do this to wait for BT module to connect; 900 may be too long, but a quick trial and error seemed to show this was ok.
                    // if we don't have this pause, then the BT module will take the data we send it and loop it back as input.
                    client.Send("Connected to Fez\r\n");
                }
                // if the state is now "disconnected", you might need to stop other processes but for this example we'll just confirm that in the debug output window
                if (btState == Bluetooth.BluetoothState.Disconnected)
                {
                    Debug.Print("\r\n" + "Program Message: Bluetooth disconnected" + "\r\n");
                }
            }
    }
}

1 Like

Thanks @ RoSchmi, reading through the Seeed forums this is actually a fairly common problem and some folks reported if you set the baud rate too high there was no way to fix it, ie they think they bricked their bluetooth adapter (these are Arduino folks)

I managed to get my problem fixed by setting up the bluetooth module to run at the speed that I was initially experimenting with (9600) and got it back working, but had to leave it as we finally had a day without rain here on Saturday so the day was spent doing yard work and Sunday was entertaining day, so I’m just now getting caught up with the going on.

Currently I’m also wresling with my ISP over poor network performance so that has taken up a bunch of my time as well. Hopefully I can get back to the project I had in mind for the bluetooth module tomorrow.

@ Brett - Hi, Brett,
would you be so kind, to test my modification of your driver. As skewworks already told I think, that the module does not start with standard 38.400 after powering up. It starts with the baudrate that was set the last time.
Kind regards
Roland

I’ll give your driver a test, but I do believe that the last baud rate is persistent and that was one of my problems in that I thought a power cycle etc would reset it.

I also added 2 items to your sample as I had them in my test driver:


            /// <summary>
            /// Exits pairing mode
            /// </summary>
            public void ExitingPairingMode()
            {
                Debug.Print("Enter Pairing Mode");
                bluetooth.serialPort.Write("\r\n+INQ=0\r\n");

            }

            /// <summary>
            /// Stops inquiring for devices
            /// </summary>
            public void StopInquireDevice()
            {
                Debug.Print("End Inquiring for devices");
                bluetooth.serialPort.Write("\r\n+INQ=0\r\n");
            }



Program Started
Program Message: Initialize Bluetooth module on Port 8 Baudrate: 38400
Message from Class Bluetooth: Set up serialPort with baudrate: 38400
Message from Class Bluetooth: Try to set BT-Module baudrate to: 38400
Message from Class Bluetooth, Reader Thread: Started
Message from Class Bluetooth: Could connect to BT-Module with baudrate 38400
Program Message: Set Bluetooth module to Client Mode

Client Mode
Program Message: Set Device Name: MySpider

Program Message: Set Device Pincode

Program Message: Set BT-Device to: Enable Auto-connect 

Message from Class Buetooth: Permit auto-connect
Program Message: Set BT-Device to: PermitBeConnected

Message from Class Bluetooth: Permit be connected
WARN: Total initialization time exceeds 10 seconds.
    : ProgramStarted is blocking execution, which means events and timers will not run properly.
    : Make sure not to use blocking code such as while(true) - use a GT.Timer instead.
Program Message: Received Data from connected BT-Device. Byte-Count: 1 

Program Message: Received Data from connected BT-Device. Byte-Count: 6 
OK

Program Message: Received Data from connected BT-Device. Byte-Count: 24 
+STNA=MySpider

OK

Program Message: Received Data from connected BT-Device. Byte-Count: 15 
WORK:SLAVER

New state:0
Program Message: Received Data from connected BT-Device. Byte-Count: 14 
+BTSTATE:0

New state:1
Program Message: Received Data from connected BT-Device. Byte-Count: 14 
+BTSTATE:1

New state:3
Program Message: Received Data from connected BT-Device. Byte-Count: 14 
+BTSTATE:3

Program Message: Received Data from connected BT-Device. Byte-Count: 1 

Program Message: Received Data from connected BT-Device. Byte-Count: 6 
OK

Program Message: Received Data from connected BT-Device. Byte-Count: 15 
WORK:SLAVER

New state:0
Program Message: Received Data from connected BT-Device. Byte-Count: 14 
+BTSTATE:0

Program Message: Received Data from connected BT-Device. Byte-Count: 13 
+STOAUT=1

Program Message: Received Data from connected BT-Device. Byte-Count: 6 
OK

New state:1
Program Message: Received Data from connected BT-Device. Byte-Count: 14 
+BTSTATE:1

New state:3
Program Message: Received Data from connected BT-Device. Byte-Count: 14 
+BTSTATE:3

Program Message: ____________________________timerSendData ticked
Program message: BT is not connected, cannot send message
New state:0
Program Message: Received Data from connected BT-Device. Byte-Count: 57 
WORK:SLAVER

+BTSTATE:0

+BTSTATE:1

+BTSTATE:3

Program Message: ____________________________timerSendData ticked
Program message: BT is not connected, cannot send message

I had the module previously set to 38400, what I’ll do is set it to 9600 and then try it again and see if it resets the baud rate.

I tried this:

bluetooth.serialPort.BaudRate = 9600;

and got this:

Otherwise doing:

bluetooth.SetDeviceBaud(9600);

Doesn’t seem to cause any problems on next startup of the device.

The commands:
e.g. bluetooth.serialPort.BaudRate = 9600
and
e.g. bluetooth.SetDeviceBaud(9600);

should not be used from outside the driver itself. I think there should be no public access to this command / field in future driver versions.

the commands will not work properly,

Changes of the baudrate should only be made in the Initial command where the constructor is called.

like:
const long BT_Device_Baudrate = 9600;
const int MySocketNumber = 8;


bluetooth = new Bluetooth(MySocketNumber, BT_Device_Baudrate);

or just
bluetooth = new Bluetooth(8, 9600);

The command: bluetooth.SetDeviceBaud(9600);

should better be removed from the public methods of the driver (it’s from the original Version).
The command is programmed “suicide”. The baudrate of the BT-Module is changed without changing the baudrate of the mainboards UART. “Time to say godbye”.

Could you please try my PC Listener App to test the connection.

http://www.ghielectronics.com/community/codeshare/entry/729

Regards
Roland

1 Like

@ RoSchmi did you try this driver with a Cerberus as I get System.OutOfMemoryException pretty much as soon as I get a Bluetooth connection.

The original driver chokes too as the NeuroSky MindWave chucks a lot of data.

@ Duke Nukem - Until now I used it on a Spider only to send test-data in the form of a short message every second to a PC, where I accepted the data with my “PC Bluetooth Serial Listener App” http://www.ghielectronics.com/community/codeshare/entry/729
Yesterday evening I tried it on a Cerbuino Bee where in preliminary tests I saw that I hat to use a longer thread.sleep of at least 800 ms at this place in the driver:


this.reset.Write(true);
  // Tests revealed that at least 470 msec are needed
  // Thread.Sleep(600);
      Thread.Sleep(600);

To use the driver to accept data from another device with high data rate all the Debug.Print commands should be commented out.
I also think, that one should have a means to switch off the parsing of the incomming data in the “runReaderThread()” once the bluetooth connection is established. I think this parsing needs a lot of time and resources. I think it would also be faster to process the incoming data with a Byte Array than to process them with strings.

Would be nice, if some interested folks could help to test and improve the driver to later post it in Code Share

Regards
Roland