FluuuxTechBlog Geschrieben 28. März 2013 Melden Share Geschrieben 28. März 2013 Objekte in Unity über den COM-Port mit Arduino steuern Da ich wieder vermehrt mit Unity herum experimentiere und ich Arduino liebe, habe ich mir gedacht dass es doch interessant wäre, zu sehen, wie sich ein Objekt über Buttons am Arduino steuern lässt. Zusätzlich fände ich es schön, wenn bei einer Kollision meines Objekts in Unity mit einem anderen Objekt, eine LED am Arduino aufblinken würde. Heute möchte ich euch nun am Ergebnis meiner Experimente teilhaben lassen. Ziel meines Experiments ist es, die Kugel zwischen den zwei Würfeln mit den beiden Buttons am Arduino nach Links und Rechts zu bewegen. Wenn die Kugel mit dem linken Würfel kollidiert, soll eine LED am Arduino dreimal aufblinken. Bei einer Kollision der Kugel mit dem rechten Würfel, soll eine andere LED am Arduino fünfmal aufblinken. Die Datenübertragung vom Arduino an Unity und auch die Rückmeldungen von Unity an den Arduino werden über einen COM-Port der seriellen Schnittstelle geregelt. Arduino Aufbau der Steuerung für die Steuerung und die Kollisionsanzeige benötigen wir einen Arduino, ein Breadboard, zwei Buttons, 2 LEDs, 4 Widerstände und ein paar Kabel um das Ganze zu verbinden. Arduino Sketch Fangen wir also mit dem Arduino Sketch an, das folgendes tut. Ein Zeichen über die Serielle Schnittstelle senden wenn ein Button gedrückt wird. Darauf warten das Zeichen über die Serielle Schnittstelle empfangen werden und entsprechend mit dem Blinken einer LED darauf reagieren. /****************************************************************************** * Projekt: Daten über Seriellen Port an Unity senden und von Unity empfangen * * Autor: Enrico Sadlowski * * Erstellungsdatum: 27.03.2013 * * Letzte Aktualisierung: 28.03.2013 * * * * Beschreibung: * *-----------------------------------------------------------------------------* * Zeichen an Unity senden und von unity empfangen und entsprechend reagieren. * * Daten die an Unity gesendet werden, müssen durch Unity ausgewertet werden * * Daten die von Unity empfangen werden, müssen in Arduino ausgewertet werden. * * ******************************************************************************/ int inByte = 0; void setup() { Serial.begin(9600); pinMode(6, OUTPUT); pinMode(7, OUTPUT); } void loop() { // Zeichen an Unity senden if(digitalRead(8) == HIGH) // Button 1 wurde gedrückt sendCharToUnity(2); // Zeichen 2 an Unity senden if(digitalRead(9) == HIGH) // Button 2 wurde gedrückt sendCharToUnity(1); // Zeichen 1 an Unity senden //Zeichen von Unity empfangen if (Serial.available() > 0) // Daten werden empfangen { inByte = Serial.read(); // Zeichen vom Seriellen Port in inByte ablegen switch(inByte) // Abfrage welches Zeichen empfangen wurde { case 54: // Zeichen 6 von Unity empfangen sendCharToUnity(3); // Zeichen 3 an Unity senden und 10ms Pause blinkLEDandOff(6, 2); // led an Pin 6 zweimal aufblinken lassen break; case 55: // Zeichen 7 von Unity empfangen sendCharToUnity(4); // Zeichen 4 an Unity senden und 10ms Pause blinkLEDandOff(7, 2); // led an Pin 7 zweimal aufblinken lassen break; } } } /* LED blinken lassen led = pin an dem die LED hängt interval = Angabe wie oft die LED aufblinken soll */ void blinkLEDandOff(byte led, byte interval) { for(int i=0;i<interval;i++) { digitalWrite(led, HIGH); delay(100); digitalWrite(led, LOW); delay(100); } } /* einzelnes Zeichen an Unity senden */ void sendCharToUnity(char Zeichen) { Serial.write(Zeichen); Serial.flush(); delay(10); } Unity In Unity habe ich einen Würfel mit den Abmessungen (X=50, Y=0,1 und Z=10) erstellt, der als Boden herhalten musste. Darauf habe ich zwei Würfel und eine Kugel in den Standardabmessungen erstellt. Diese Objekte habe ich mit etwas Abstand nebeneinander platziert, wobei die Kugel sich zwischen den Würfeln befindet und meinen steuerbaren Player darstellt. Damit sich alle 3 Objekte physikalisch korrekt verhalten wenn sich diese berühren, habe ich diesen jeweils einen Rigidbody zugewiesen. Ich möchte das LED1 am Arduino dann blinkt wenn meine Kugel einen der Würfel berührt. LEDs soll blinken wenn die Kugel mit dem anderen Würfel kollidiert. Damit ich die Kollision mit den verschiedenen Würfeln unterscheiden kann, habe ich zwei neue Tags mit den Namen “Blink6″ und “Blink7″ angelegt und jeweils eines der Tags den Würfeln zugeordnet. SerialPortTest.cs Als nächstes habe ich eine neue C Sharp Datei mit dem Namen “SerialPortTest.cs†angelegt. Diese Datei habe ich im Inspector der der Kugel zugewiesen. Dieses Script stellt beim starten eine Verbindung zum Seriellen COM-Port 3 her, mit dem auch der Arduino verbunden ist. Wenn Sie Ihr Unity-Projekt später ausführen wollen, beachten Sie bitte, dass Sie den Serial Monitor der Arduino Software nicht geöffnet haben, da sonst keine Verbindung zum COM-Port hergestellt werden kann, da diese in diesem Fall bereits geöffnet ist. In der Funktion “Update†wird nun ständig geprüft ob Werte über den Seriellen Port empfangen werden. Wenn Sie auf dem Arduino Button1 drücken, dann wird das Zeichen 1 empfangen und die Kugel bewegt sich nach rechts. Wenn die Kugel nun den Würfel mit dem Tag “Blink6″ berührt, wird eine Kollision erkannt und das Zeichen 6 wird an den Arduino gesendet. Der Arduino wiederum empfängt dieses Zeichen und reagiert darauf indem er LED 1 dreimal blinken lässt. Zusätzlich wird das Zeichen 3 zurück an Unity gesendet. Wie Sie nun auf diese Rückgabe reagieren bleibt Ihrer Fantasie überlassen. ich gebe hier lediglich eine Meldung aus. /****************************************************************************** * Projekt: Daten über Seriellen Port an Unity senden und von Unity empfangen * * Autor: Enrico Sadlowski * * Erstellungsdatum: 27.03.2013 * * Letzte Aktualisierung: 28.03.2013 * * * * Beschreibung: * *-----------------------------------------------------------------------------* * Zeichen über die serielle Schnittstelle empfangen um ein Objekt zu steuern * * Bei Kollision eines Objektes mit anderen Objekten ein Zeichen über die * * Serielle Schnittstelle an den Arduino senden und dort eine LED blinken * * lassen. * ******************************************************************************/ using UnityEngine; using System.Collections; using System.IO.Ports; public class SerialPortTest : MonoBehaviour { public float speed; private float amountToMove; private bool collides = false; SerialPort sp = new SerialPort("COM3", 9600); void Start () { OpenConnection(); speed = 10; } void Update() { amountToMove = speed * Time.deltaTime; if(sp.IsOpen) { try { //Daten vom Arduino empfangen //Objekt ueber Arduino steuern (1=links, 2=rechts) MoveObject(sp.ReadByte()); print(sp.ReadByte()); } catch (System.Exception) { } } } /* Player ist mit Objekt kollidiert */ void OnCollisionEnter(Collision col) { if(col.gameObject.tag == "Blink6") { collides = true; print ("collidiert"); SendDataToArduino("6"); } if(col.gameObject.tag == "Blink7") { collides = true; print ("collidiert"); SendDataToArduino("7"); } } /* Anwendung wird geschlossen */ void OnApplicationQuit() { sp.Close(); print ("COM-Port geschlossen"); } /* Mit COM-Port verbinden */ public void OpenConnection() { if (sp != null) { if (sp.IsOpen) { sp.Close(); print("COM-Port schliessen, weil er bereits geoeffnet war!"); } else { sp.Open(); // COM-Port Verbindung öffnen sp.ReadTimeout = 1; print("COM-Port geoeffnet!"); } } else { if (sp.IsOpen) print("COM-Port ist bereits geoeffnet!"); else print("Port == null"); } } /* Player über den Arduino steuern 1=links, 2=rechts */ void MoveObject(int Direction) { switch (Direction) { case 1: transform.Translate(Vector3.right * amountToMove, Space.World); break; case 2: transform.Translate(Vector3.left * amountToMove, Space.World); break; case 3: print("Ich habe nach der Kollision das Zeichen 3 vom Arduino empfangen"); break; case 4: print("Ich habe nach der Kollision das Zeichen 4 vom Arduino empfangen"); break; } } /* Daten an Arduino senden */ void SendDataToArduino(string Zeichen) { if(collides == true) { sp.WriteLine(Zeichen); collides = false; print (Zeichen + " wurde an Arduino gesendet"); } } } Ich hoffe ich konnte dem Einen oder Anderen mit diesem kleinen Tutorial etwas helfen. ich persönlich finde es einfach faszinierend, Objekte im Virtuellen Raum mit realen Objekten steuern zu können und auch noch Rückmeldungen aus dem Virtuellen Raum zu erhalten. Dieses Tutorial finden Sie übrigens auch in meinem FLUUUX-TechBlog 3 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Floater Geschrieben 28. März 2013 Melden Share Geschrieben 28. März 2013 Sau geil! Mehr muss man da nicht sagen!!! Werd ich bei Gelegenheit ausprobieren! =) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
AgentCodeMonk Geschrieben 28. März 2013 Melden Share Geschrieben 28. März 2013 Witzige Sache, bin zwar kein großer Arduino-Freund, aber das wär´s ja nochmal wert damit herumzufrickeln. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
skee Geschrieben 17. April 2013 Melden Share Geschrieben 17. April 2013 Ziemlich geil! Hätte auch gern so ein Ding und genug Zeit um damit rumzuspielen Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
AgentCodeMonk Geschrieben 17. April 2013 Melden Share Geschrieben 17. April 2013 Nen arduino kostet doch nur ca 30 Euronen +- Die Software fürs Coden der "Sketches" ( wer sich diese Bezeichnung hat einfallen lassen....) gibt´s eh kostenlos. Der ganze Kleinkram für´s Drumherum geht dann auf Dauer eher in´s Geld... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
FluuuxTechBlog Geschrieben 17. April 2013 Autor Melden Share Geschrieben 17. April 2013 Er hat ja geschrieben dass ihm die Zeit fehlt. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Tortelini66 Geschrieben 21. April 2013 Melden Share Geschrieben 21. April 2013 Ich hab den Text jetzt nur überflogen, aber wofür dient das ethernet-shield? Das könnte man doch auch einfach weglassen, oder hab ich was überlesen Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Carsten Geschrieben 24. April 2013 Melden Share Geschrieben 24. April 2013 Ich bin ja nicht so ein Hardwaretyp. Aber ich finde es immer super interessant auf was für Ideen manche Leute kommen. Und solche Anleitungen sind dann per se genial. Vielen Dank, profwebapps! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
pcace Geschrieben 8. Mai 2014 Melden Share Geschrieben 8. Mai 2014 Hallo, ich versuche grad verzweifelt das gleiche auf einem Mac (10.9) zum laufen zu bekommen: Hier ist der Arduino Code: void setup() { Serial.begin(9600); } void loop() { Serial.println(1); Serial.flush(); delay(1000); Serial.println(2); Serial.flush(); delay(1000); } und hier der Unity c# code: using UnityEngine; using System.Collections; using System.IO.Ports; public class MoveSphere : MonoBehaviour { public float speed; private float amountToMove; SerialPort sp = new SerialPort("COM3", 9600); void Start (){ sp.Open (); sp.ReadTimeout = 1; } void Update (){ amountToMove = speed * Time.deltaTime; if (sp.IsOpen) { try { MoveObject(sp.ReadByte()); print(sp.ReadByte()); } catch (System.Exception){ } } } void MoveObject (int Direction) { if (Direction == 1){ gameObject.transform.localScale += new Vector3(0,0,0.1f); } if (Direction == 2){ gameObject.transform.localScale += new Vector3(0,0,-0.1f); } } } Ich bekomme leider immer IOException: No such file or directory. Ist das eine MacOSX sache oder mache ich irgendetwas komplett falsch? Gruß Pcace Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Schlumpf Geschrieben 8. Mai 2014 Melden Share Geschrieben 8. Mai 2014 wenn ich das damals in der ausbildung richtig gelernt habe nutzt mac eine andere art der port bezeichnung... du sprichst sie unter mac so an wie es jemand unter windoof machen würde das geht nich denk ich schau mal hier z.b. http://answers.unity...to-arduino.html Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
pcace Geschrieben 8. Mai 2014 Melden Share Geschrieben 8. Mai 2014 Oh, natürlich, ich habe natürlich bei mir im Code nicht COM3 stehen... da steht /dev/tty.usbmodemfa131 (das ist der angeschlossene Arduino) das problem schein aber ein ganz anderes zu sein: System.IO.Ports cannot be used on Mac's currently therefore this won't work on a Mac has something to do with Serial Ports and the Mono version implemented in Unity Das jedenfalls habe ich in dem Verlinkten Thread gelesen... Ideen wie man das behben könnte? Gruß Pcace Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
pcace Geschrieben 8. Mai 2014 Melden Share Geschrieben 8. Mai 2014 Ok, ich habe es jetzt einfach so gelöst: http://www.uniduino.com/ kostet ein wenig, funktioniert aber ohne Probleme (jedenfalls bisher ) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
FluuuxTechBlog Geschrieben 9. Mai 2014 Autor Melden Share Geschrieben 9. Mai 2014 Einen Beitrag zu uniduino habe ich in meinem Blog auch geschrieben (UNIDUINO – Helligkeit in Unity3D der Umgebungshelligkeit der realen Welt anpassen). Ist echt super was man damit machen kann. Falls es Dich interessiert, den Artikel kannst Du hier lesen. http://fluuux.de/2013/05/uniduino-helligkeit-in-unity3d-der-umgebungshelligkeit-der-realen-welt-anpassen/ Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.