Files
Aether-Engine/Assets/Shatalmic/Example/ArduinoHM10Test/ArduinoHM10Test.cs
2026-02-20 17:53:43 +01:00

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");
});
}
}