Issues with Bluetooth module

Hi,

I’m pretty new to Gadgeteer. I bought a FEZ Cerberus starter Kit and a bluetooth module.
I’m trying to get it to connect to my PC, my phone or my MS surface but none of it seems to work. I’m using the sample code from the GHI website.

I tried the official driver (GTM.GHIElectronics.Bluetooth 4.2.101.0) as well as the driver from RoSchmi.

With the official driver I got an System.ArgumentOutOfRangeException so I switched to RoSchmi’s driver.

Here’s the code that I’m using.


public partial class Program
    {
        Bluetooth bluetooth;
        void ProgramStarted()
        {
            bluetooth = new Bluetooth(2);
            bluetooth.SetDeviceName("Gadgeteer");

            bluetooth.BluetoothStateChanged += new Bluetooth.BluetoothStateChangedHandler(bluetooth_BluetoothStateChanged);
            bluetooth.DataReceived += new Bluetooth.DataReceivedHandler(bluetooth_DataReceived);

            joystick.JoystickPressed += joystick_JoystickPressed;
           
        }

        void bluetooth_BluetoothStateChanged(Bluetooth sender, Bluetooth.BluetoothState btState)
        {
            Debug.Print(btState.ToString());
        }

        void bluetooth_DataReceived(Bluetooth sender, string data)
        {
            Debug.Print(data);
            //sender.ClientMode.SendLine(data); //echoes the data back to the device.
        }

        void joystick_JoystickPressed(GTM.GHIElectronics.Joystick sender, GTM.GHIElectronics.Joystick.JoystickState state)
        {
            if (!bluetooth.IsConnected)
            {
                bluetooth.ClientMode.EnterPairingMode();
            }
        }   
    }

The initial output is:

Using mainboard GHI Electronics FEZCerberus version 1.1
Message from Class Bluetooth 1: Baudrate set to 38400
Message from Class Bluetooth: Try to set BT-Module baudrate to: 38400
Message from Class Bluetooth: Could connect to BT-Module with baudrate 38400 in 16.6816 msec

OK
WORK:SLAVER
0
+BTSTATE:0
1
+BTSTATE:1
3
+BTSTATE:3
Der Thread ‘’ (0x3) hat mit Code 0 (0x0) geendet.
CONNECT:FAIL
1
+BTSTATE:1

Then I press the joystick and the output is

Enter Pairing Mode
+INQ=1
OK
2
+BTSTATE:2

And the red and blue LEDs are flashing.
I then try to connect to the module from one of my devices (PC, Phone, Surface). I don’t use a PIN.

The PC will show the Gadgeteer as connected for a few seconds but the module is still flashing red and blue and it’s not getting into connected mode.

When I try to send something from the PC to the module, the module does not receive it and the code on the PC just hangs.

I updated the FEZ Cerberus with FEZ Config to 4.2.6.1.

Is there anything that I miss?

Any help is much appreciated.

Thanks,
Sebastian

Hi,
there are some things missing in your code. You did nod specify a Pairing Password. I’m back in a minute. Are you actually on your PC?

Hi Sebastian,
welcome to the Forum.
try as follows:
include the classes Bluetooth.cs and serialbuffer.cs in your Project.
Change the Namespace of the class SerialBuffer to the Namespace of your project.
Then use this code as Program.cs:


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.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;

using Gadgeteer.Modules.GHIElectronics;
using Gadgeteer.Modules.RoSchmi;

namespace BluetoothMouserBasti
{
    public partial class Program
     {
         //**********    Presets:  Parameter to be changed by users  ***************************

         const string MyDeviceName = "Gadgeteer";   // Device Name
         const string MyPinCode = "0000";            // Pin Code
         const int MySocketNumber = 2;               // 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 bool ReadMode_ByteArray = true;       // false: data are received as strings -Event: bluetooth_DataReceived
         // true: data are received as byte array-Event: bluetooth_DataByteArrayReceived

         const bool FastReadMode = true;             // true: switch to transmit without parsing
         // false: data are always parsed for BT-module messages

         const int MyEventDelay = 20;                // Choose higher value if data received events queue up ( 20 = standard)
         // has no effect in ReadMode_ByteArray Mode in combination with FastReadMode 

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

         //**************** End Parameter to be changed by user ***************************
         // timerSendData is used to fire in interval to send data to the BT-Module
         GT.Timer timerSendData;

         // timerEnterPairing is used to enter pairing mode automatically
         GT.Timer timerEnterPairing;

         string dataLine1 = null;      // used to process incoming data in eventhandler: bluetooth_DataReceived (as String)
         string dataLine2 = null;      // used to process incoming data in eventhandler: bluetooth_DataByteArrayReceived (as Byte Array)

         byte[] ReceivedBytes;         // used to process incoming data in eventhandler: bluetooth_DataReceived (as String)

         SerialBuffer mySerialBuffer;  // used to connect incoming data chunks and split after LineFeed (0x0A)

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

         void ProgramStarted()
         {
             joystick.JoystickPressed += joystick_JoystickPressed;

             // Set a timer to enter pairing mode after 3 seconds
             timerEnterPairing = new GT.Timer(3000, GT.Timer.BehaviorType.RunOnce);
             timerEnterPairing.Tick += new GT.Timer.TickEventHandler(timerEnterPairing_Tick);

             // 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);

             bluetooth.EventDelay = MyEventDelay;  // Choose higher value in "Presets" if data received events queue up ( 20 = standard)
             // has no effect in ReadMode_ByteArray Mode in combination with FastReadMode 

             // Set the Mode to receive data as Strings or as Byte Array depending on the settings in "Presets"
             bluetooth.SetReadMode_ByteArray(ReadMode_ByteArray);

             // Set up eventhandler for state changes
             // bluetooth.BluetoothStateChanged += new Bluetooth.BluetoothStateChangedHandler(bluetooth_BluetoothStateChanged);
             bluetooth.BluetoothStateChanged += bluetooth_BluetoothStateChanged;


             // Set up eventhandler to receive data from the Bluetooth module as Strings or as Byte Arrays (only one is needed)
             //bluetooth.DataReceived += new Bluetooth.DataReceivedHandler(bluetooth_DataReceived);
             bluetooth.DataReceived +=bluetooth_DataReceived;
             //bluetooth.DataByteArrayReceived += new Bluetooth.DataByteArrayReceivedHandler(bluetooth_DataByteArrayReceived);
             bluetooth.DataByteArrayReceived +=bluetooth_DataByteArrayReceived;

             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);                     // time was not tested

             Debug.Print("Program Message: Set Device Pincode" + "\r\n");
             bluetooth.SetPinCode(MyPinCode);
             Thread.Sleep(2000);                     // time was not tested

             Debug.Print("Program Message: Set BT-Device to: Enable Auto-connect " + "\r\n");
             bluetooth.PermitAutoConnect();
             Thread.Sleep(200);                      // time was not tested

             Debug.Print("Program Message: Set BT-Device to: PermitBeConnected" + "\r\n");
             bluetooth.PermitBeConnected();
             Thread.Sleep(200);                      // time was not tested

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

             mySerialBuffer = new SerialBuffer(256);

             timerSendData.Start();
             timerEnterPairing.Start();
         }

         void joystick_JoystickPressed(GTM.GHIElectronics.Joystick sender, GTM.GHIElectronics.Joystick.JoystickState state)
         {
             if (!bluetooth.IsConnected)

             {
                 // 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();
                 }
                
             }
         }
         #region timerSendData_Tick   Sends a message over the Bluetooth Connection
         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, "  + "\r\n");
                
             }
             else
             {
                 Debug.Print("Program message: BT is not connected, cannot send message");
             }
         }
         #endregion


         #region timerEnterPairing_Tick    Enter Pairing Mode
         void timerEnterPairing_Tick(GT.Timer timer)
         {
             if (!bluetooth.IsConnected)
             {
                 Debug.Print("Enter pairing mode by timer event");
                 client.EnterPairingMode();
             }
         }
         #endregion

         // You have the choice to receive the data as strings or as ByteArrays. You need only one

         #region  Eventhandler --  Receive data as Strings
         // Select this output mode with the  bluetooth.SetReadMode_ByteArray(false) command
         private void bluetooth_DataReceived(Bluetooth sender, string data)
         {
             ReceivedBytes = System.Text.UTF8Encoding.UTF8.GetBytes(data);
             mySerialBuffer.LoadSerial(ReceivedBytes, 0, ReceivedBytes.Length);

             // To see the chunks of data we can activate this Debug.Print
             //Debug.Print("\r\n Program Message: Received chunk of data (String Mode). Byte-Count: " + data.Length.ToString() + " Data: " + HexEncoding.ToString(ReceivedBytes, 0, ReceivedBytes.Length) + "\r\n" + data + "\r\n");
             
             while ((dataLine1 = mySerialBuffer.ReadLine()) != null)
             {
                  Debug.Print("Line Received: " + dataLine1);
                 // If we have a RS232 module connected we can send the received data to another PC
                 // rs232.serialPort.Write(dataLine1 + "\r\n");
                 // parse the data sentence here if needed
             }
             
         }
         #endregion

         #region  Eventhandler --  Receive data as Byte Arrays
         // Select this output mode with the  bluetooth.SetReadMode_ByteArray(true) command
         void bluetooth_DataByteArrayReceived(Bluetooth sender, byte[] data, int startIndex, int ByteCount)
         {
             if (ByteCount < 100)   // for short messages we send it over rs232
             {
                 mySerialBuffer.LoadSerial(data, startIndex, ByteCount);
             }
             else                  // for high speed data we only send the statistics
             {
               //  rs232.serialPort.Write("Bytes Transferred: " + BytesTransferred.ToString() + "  Bytes per event: " + ByteCount.ToString() + " Estimated Baudrate: " + baudrate.ToString() + " Received Events per sec:  " + eventspersec.ToString() + "\r\n");
             }
             while ((dataLine2 = mySerialBuffer.ReadLine()) != null)
             {
                 // If we have a RS232 module connected we can send the received data to another PC
                 // rs232.serialPort.Write(dataLine2 + "\r\n");
                 Debug.Print(dataLine2 + "\r\n");

                 // parse the data sentence here if needed
             }
         }
         #endregion

         #region  Eventhandler signalizing that the BTSTATE of the Bluetooth module has changed
         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("\r\n Program Message: BT-Connection established, BTSTATE: " + btState.ToString() + "\r\n");

                 bluetooth.SetFastReadMode(FastReadMode);  // Set fastReadMode, depending on the flag in presets

                 Thread.Sleep(1000);      // do this to wait for BT module to connect; 
                 client.Send("\r\nConnected 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.Connected)
             {
                 // Debug.Print("\r\n" + "Program Message: Bluetooth disconnected, BTSTATE: " +  btState.ToString() + "\r\n");
             }
         }
         #endregion
     } 
}

 

@ RoSchmi -

Hi,

thanks for the hint with the pin.
I tried that already but I did not try to actually send a message from the PC to the module.
I thought that the module must first change its state to CONNECTED before I can send a message to it.

It’s working now. :slight_smile:

So my ProgramStarted method now looks like:



 void ProgramStarted()
        {
            bluetooth = new Bluetooth(2);
            bluetooth.SetDeviceName("Gadgeteer");
            bluetooth.SetPinCode("0000");

            bluetooth.BluetoothStateChanged += new Bluetooth.BluetoothStateChangedHandler(bluetooth_BluetoothStateChanged);
            bluetooth.DataReceived += new Bluetooth.DataReceivedHandler(bluetooth_DataReceived);

            joystick.JoystickPressed += joystick_JoystickPressed;
           
        }

Thanks,
Sebastian

@ MouserBasti -
Great that it works for you. which Driver did you use?

if you want, you can use the FEZ/PC Bluetooth File Transfer Server/Client
https://www.ghielectronics.com/community/codeshare/entry/823
to communicate from PC to FEZ Device.
Cheers
Roland

@ RoSchmi -
Hi Roland,

I’m currently using your driver which works fine.
I want to build a bluetooth device that sends temperatur and air pressure data to my tablet.

Thanks,
Sebastian