274 lines
7.2 KiB
C#
274 lines
7.2 KiB
C#
/* This is an example to show how to connect to 2 HM-10 devices
|
|
* that are connected together via their serial pins and send data
|
|
* back and forth between them.
|
|
*/
|
|
|
|
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using UnityEngine.UI;
|
|
using System.Text;
|
|
|
|
public class ArduinoHM10Test : MonoBehaviour
|
|
{
|
|
public string DeviceName = "DSD TECH";
|
|
public string ServiceUUID = "FFE0";
|
|
public string Characteristic = "FFE1";
|
|
|
|
public Text HM10_Status;
|
|
public Text BluetoothStatus;
|
|
public GameObject PanelMiddle;
|
|
public Text TextToSend;
|
|
|
|
enum States
|
|
{
|
|
None,
|
|
Scan,
|
|
Connect,
|
|
RequestMTU,
|
|
Subscribe,
|
|
Unsubscribe,
|
|
Disconnect,
|
|
Communication,
|
|
}
|
|
|
|
private bool _workingFoundDevice = true;
|
|
private bool _connected = false;
|
|
private float _timeout = 0f;
|
|
private States _state = States.None;
|
|
private bool _foundID = false;
|
|
|
|
// this is our hm10 device
|
|
private string _hm10;
|
|
|
|
public void OnButton(Button button)
|
|
{
|
|
if (button.name.Contains ("Send"))
|
|
{
|
|
if (string.IsNullOrEmpty (TextToSend.text))
|
|
{
|
|
BluetoothStatus.text = "Enter text to send...";
|
|
}
|
|
else
|
|
{
|
|
SendString (TextToSend.text);
|
|
}
|
|
}
|
|
else if (button.name.Contains("Toggle"))
|
|
{
|
|
SendByte (0x01);
|
|
}
|
|
}
|
|
|
|
void Reset ()
|
|
{
|
|
_workingFoundDevice = false; // used to guard against trying to connect to a second device while still connecting to the first
|
|
_connected = false;
|
|
_timeout = 0f;
|
|
_state = States.None;
|
|
_foundID = false;
|
|
_hm10 = null;
|
|
PanelMiddle.SetActive (false);
|
|
}
|
|
|
|
void SetState (States newState, float timeout)
|
|
{
|
|
_state = newState;
|
|
_timeout = timeout;
|
|
}
|
|
|
|
void StartProcess ()
|
|
{
|
|
BluetoothStatus.text = "Initializing...";
|
|
|
|
Reset ();
|
|
BluetoothLEHardwareInterface.Initialize (true, false, () => {
|
|
|
|
SetState (States.Scan, 0.1f);
|
|
BluetoothStatus.text = "Initialized";
|
|
|
|
}, (error) => {
|
|
|
|
BluetoothLEHardwareInterface.Log ("Error: " + error);
|
|
});
|
|
}
|
|
|
|
// Use this for initialization
|
|
void Start ()
|
|
{
|
|
HM10_Status.text = "";
|
|
|
|
StartProcess ();
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update ()
|
|
{
|
|
if (_timeout > 0f)
|
|
{
|
|
_timeout -= Time.deltaTime;
|
|
if (_timeout <= 0f)
|
|
{
|
|
_timeout = 0f;
|
|
|
|
switch (_state)
|
|
{
|
|
case States.None:
|
|
break;
|
|
|
|
case States.Scan:
|
|
BluetoothStatus.text = "Scanning for HM10 devices...";
|
|
|
|
BluetoothLEHardwareInterface.ScanForPeripheralsWithServices (null, (address, name) => {
|
|
|
|
// we only want to look at devices that have the name we are looking for
|
|
// this is the best way to filter out devices
|
|
if (name.Contains (DeviceName))
|
|
{
|
|
_workingFoundDevice = true;
|
|
|
|
// it is always a good idea to stop scanning while you connect to a device
|
|
// and get things set up
|
|
BluetoothLEHardwareInterface.StopScan ();
|
|
BluetoothStatus.text = "";
|
|
|
|
// add it to the list and set to connect to it
|
|
_hm10 = address;
|
|
|
|
HM10_Status.text = "Found HM10";
|
|
|
|
SetState (States.Connect, 0.5f);
|
|
|
|
_workingFoundDevice = false;
|
|
}
|
|
|
|
}, null, false, false);
|
|
break;
|
|
|
|
case States.Connect:
|
|
// set these flags
|
|
_foundID = false;
|
|
|
|
HM10_Status.text = "Connecting to HM10";
|
|
|
|
// note that the first parameter is the address, not the name. I have not fixed this because
|
|
// of backwards compatiblity.
|
|
// also note that I am note using the first 2 callbacks. If you are not looking for specific characteristics you can use one of
|
|
// the first 2, but keep in mind that the device will enumerate everything and so you will want to have a timeout
|
|
// large enough that it will be finished enumerating before you try to subscribe or do any other operations.
|
|
BluetoothLEHardwareInterface.ConnectToPeripheral (_hm10, null, null, (address, serviceUUID, characteristicUUID) => {
|
|
|
|
if (IsEqual (serviceUUID, ServiceUUID))
|
|
{
|
|
// if we have found the characteristic that we are waiting for
|
|
// set the state. make sure there is enough timeout that if the
|
|
// device is still enumerating other characteristics it finishes
|
|
// before we try to subscribe
|
|
if (IsEqual (characteristicUUID, Characteristic))
|
|
{
|
|
_connected = true;
|
|
SetState (States.RequestMTU, 2f);
|
|
|
|
HM10_Status.text = "Connected to HM10";
|
|
}
|
|
}
|
|
}, (disconnectedAddress) => {
|
|
BluetoothLEHardwareInterface.Log ("Device disconnected: " + disconnectedAddress);
|
|
HM10_Status.text = "Disconnected";
|
|
});
|
|
break;
|
|
|
|
case States.RequestMTU:
|
|
HM10_Status.text = "Requesting MTU";
|
|
|
|
BluetoothLEHardwareInterface.RequestMtu(_hm10, 185, (address, newMTU) =>
|
|
{
|
|
HM10_Status.text = "MTU set to " + newMTU.ToString();
|
|
|
|
SetState(States.Subscribe, 0.1f);
|
|
});
|
|
break;
|
|
|
|
case States.Subscribe:
|
|
HM10_Status.text = "Subscribing to HM10";
|
|
|
|
BluetoothLEHardwareInterface.SubscribeCharacteristicWithDeviceAddress (_hm10, ServiceUUID, Characteristic, null, (address, characteristicUUID, bytes) => {
|
|
|
|
HM10_Status.text = "Received Serial: " + Encoding.UTF8.GetString (bytes);
|
|
});
|
|
|
|
// set to the none state and the user can start sending and receiving data
|
|
_state = States.None;
|
|
HM10_Status.text = "Waiting...";
|
|
|
|
PanelMiddle.SetActive (true);
|
|
break;
|
|
|
|
case States.Unsubscribe:
|
|
BluetoothLEHardwareInterface.UnSubscribeCharacteristic (_hm10, ServiceUUID, Characteristic, null);
|
|
SetState (States.Disconnect, 4f);
|
|
break;
|
|
|
|
case States.Disconnect:
|
|
if (_connected)
|
|
{
|
|
BluetoothLEHardwareInterface.DisconnectPeripheral (_hm10, (address) => {
|
|
BluetoothLEHardwareInterface.DeInitialize (() => {
|
|
|
|
_connected = false;
|
|
_state = States.None;
|
|
});
|
|
});
|
|
}
|
|
else
|
|
{
|
|
BluetoothLEHardwareInterface.DeInitialize (() => {
|
|
|
|
_state = States.None;
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
string FullUUID (string uuid)
|
|
{
|
|
return "0000" + uuid + "-0000-1000-8000-00805F9B34FB";
|
|
}
|
|
|
|
bool IsEqual(string uuid1, string uuid2)
|
|
{
|
|
if (uuid1.Length == 4)
|
|
uuid1 = FullUUID (uuid1);
|
|
if (uuid2.Length == 4)
|
|
uuid2 = FullUUID (uuid2);
|
|
|
|
return (uuid1.ToUpper().Equals(uuid2.ToUpper()));
|
|
}
|
|
|
|
void SendString(string value)
|
|
{
|
|
var data = Encoding.UTF8.GetBytes (value);
|
|
// notice that the 6th parameter is false. this is because the HM10 doesn't support withResponse writing to its characteristic.
|
|
// some devices do support this setting and it is prefered when they do so that you can know for sure the data was received by
|
|
// the device
|
|
BluetoothLEHardwareInterface.WriteCharacteristic (_hm10, ServiceUUID, Characteristic, data, data.Length, false, (characteristicUUID) => {
|
|
|
|
BluetoothLEHardwareInterface.Log ("Write Succeeded");
|
|
});
|
|
}
|
|
|
|
void SendByte (byte value)
|
|
{
|
|
byte[] data = new byte[] { value };
|
|
// notice that the 6th parameter is false. this is because the HM10 doesn't support withResponse writing to its characteristic.
|
|
// some devices do support this setting and it is prefered when they do so that you can know for sure the data was received by
|
|
// the device
|
|
BluetoothLEHardwareInterface.WriteCharacteristic (_hm10, ServiceUUID, Characteristic, data, data.Length, false, (characteristicUUID) => {
|
|
|
|
BluetoothLEHardwareInterface.Log ("Write Succeeded");
|
|
});
|
|
}
|
|
}
|