using System.Collections; using System.Collections.Generic; using UnityEngine; using OSC.NET; using System; using UnityEngine.Events; using System.Threading; namespace OSCFirmata { public class FirmataControl : MonoBehaviour { public string sendAddress = "localhost"; public int sendPort = 3434; public int receievePort = 3435; public enum ControlType { set_digital, set_analog, } public PinCommand[] pins; public PinCommand[] inPins; private Dictionary inPinMap = new Dictionary(); private bool is_receiving_thread_running = false; private Thread receivingThread; // Use this for initialization void Start() { _oscSender = new OSCTransmitter(sendAddress, sendPort); _oscReceiever = new OSCReceiver(receievePort); receivingThread = new Thread(receivingService); receivingThread.Start(); // inPins = new PinCommand[1]; } // Update is called once per frame protected void Update() { foreach (var pin in pins) { if (_oscSender != null) _oscSender.Send(pin.toOSC()); } lock (inPinMap) { foreach (PinCommand pin in inPins) { if (inPinMap.ContainsKey(pin.pin)) { //if (pin.value != inPinMap[pin.pin].value) { pin.value = inPinMap[pin.pin].value; pin.valueChangeEvent.Invoke(pin.value); } } } } } private void OnDestroy() { is_receiving_thread_running = false; _oscReceiever.Close(); receivingThread.Join(); } protected OSCTransmitter _oscSender; protected OSCReceiver _oscReceiever; public enum CommandType { report_pin, set_pin, } public enum PinMode { DIGITAL_INPUT = 0x00, DIGITAL_OUTPUT = 0x01, ANALOG_INPUT = 0x02, PWM = 0x03, SERVO = 0x04, SHIFT = 0x05, I2C = 0x06, ONEWIRE = 0x07, STEPPER = 0x08, ENCODER = 0x09, SERIAL = 0x0A, INPUT_PULLUP = 0x0B, } private void processMessage(OSCMessage msg) { //Debug.Log(msg.ToString()); #if true PinCommand pin = PinCommand.fromOSC(msg); //if(pin.pin == 8) //Debug.Log(msg.ToString()); lock (inPinMap) { if (inPinMap.ContainsKey(pin.pin)) { inPinMap[pin.pin] = pin; } else { inPinMap.Add(pin.pin, pin); } } #endif } [System.Serializable] public class PinCommand { public ControlType controlType = ControlType.set_digital; public int pin = 0; [Range(0f, 1f)] public float value; [Serializable] public class ValueChangeedEvent : UnityEvent { } public ValueChangeedEvent valueChangeEvent; CommandType commandType = CommandType.set_pin; PinMode mode; public OSCMessage toOSC() { string address = "/rqst/" + commandType; OSCMessage msg = new OSCMessage(address); switch (controlType) { case ControlType.set_analog: mode = PinMode.PWM; break; case ControlType.set_digital: mode = PinMode.DIGITAL_OUTPUT; break; } msg.Append(pin); msg.Append(mode.ToString()); msg.Append(value); return msg; } public static PinCommand fromOSC(OSCMessage msg) { PinCommand pin = new PinCommand(); if (msg.Address != "/rspn/report_pin") return null; pin.pin = (int)msg.Values[0]; pin.mode = (PinMode)Enum.Parse(typeof(PinMode), (string)msg.Values[1]); pin.value = (float)msg.Values[2]; return pin; } } private void receivingService() { is_receiving_thread_running = true; while (is_receiving_thread_running) { OSCPacket packet = _oscReceiever.Receive(); while (is_receiving_thread_running && packet != null) { if (packet.IsBundle()) { //Debug.Log("IsBundle"); ArrayList messages = packet.Values; for (int i = 0; i < messages.Count; i++) { processMessage((OSCMessage)messages[i]); } } else processMessage((OSCMessage)packet); packet = _oscReceiever.Receive(); } } Debug.Log("packet = null"); } } }