Following the previous blog on how to control Unity objects with Arduino, today I will document the opposite: using Unity to control Arduino. This YouTube tutorial was the inspiration and here I will add some tips and tricks that I found to be very useful.
Code is available on GitHub containing the Arduino Script and the Unity Project used for this blog.
Requirements:
- Unity
- Arduino Uno, 3 LEDs, 3 resistors (220 ohm), wires, breadboard
What you will learn:
- How to send inputs from Unity to Arduino
Language:
- C# in Unity
- C/C++ functions for Arduino IDE
1. Play with Arduino
This is the schema that I have created for my experiment. For the creation of the schema Fritzing is a very easy online tool that allows you to create simple schema like this one by using drag and drop functionality.
Use the Arduino IDE and plug-in your breadboard and use the following script.
int gLed = 8; // choose your Pin
int yLed = 7; // choose your Pin
int rLed = 6; // choose your Pin
char myCol[20];
void setup() {
Serial.begin(9600);
pinMode(gLed, OUTPUT);
pinMode(yLed, OUTPUT);
pinMode(rLed, OUTPUT);
digitalWrite(gLed, LOW);
digitalWrite(yLed, LOW);
digitalWrite(rLed, LOW);
}
void loop() {
int lf = 10;
Serial.readBytesUntil(lf, myCol, 1); // read in any data coming in through the serial
if(strcmp(myCol, "r")==0){
digitalWrite(gLed, LOW);
digitalWrite(yLed, LOW);
digitalWrite(rLed, HIGH);
}
if(strcmp(myCol, "y")==0){
digitalWrite(gLed, LOW);
digitalWrite(yLed, HIGH);
digitalWrite(rLed, LOW);
}
if(strcmp(myCol, "g")==0){
digitalWrite(gLed, HIGH);
digitalWrite(yLed, LOW);
digitalWrite(rLed, LOW);
}
As the original author of the tutorial explains in his blog:
The following line of code
Serial.readBytesUntil(lf, myCol, 1);
allows the Arduino to read in any data coming in through the serial until one of two events happen:
1. Either a line feed character is detected; this is identified by "lf" (which is set to 10) or
2. A certain amount of bytes have been read in (third argument), and for this example is set to just one byte. The data is stored in the variable myCol, which is set to char and a limit of 20. In readBytesUntil this is the second argument.
Once you have uploaded the code to Arudino, let’s open Unity.
2. Create a Unity project
You should be able to create a new project. (I am currently using: 2020.1.1f1 Version)
Important: Change the setting of the player by going into Edit --> Project settings --> Player --> API Compatibility Level --> .NET 4.x (not subset)
For this project it's necessary for you to create
Empty Object in which you will attach the script "TrafficLight.cs"
3 Spheres (with different colors) and in each attach the script "callRed.cs", "callGreen.cs", "callYellow.cs"
In order to make the three spheres clickable you will need to add a RigidBody and a Box Collider.
For simplicity, I have included the complete Unity Project on GitHub.
Important: In "TrafficLight.cs" you will need to change the Port name (COM port in Windows) of your Arduino. How to find your Port name? When you create a new serial port you should include the port name. On a Mac, an easy way to do this is to go on the command line and use:
ls /dev/tty.*
to list all the possible port available.
If you want to rename the script files, make sure to name your C# file the same as your class name.
Getting TimeOut Exceptions?
If you are following the original tutorial, you might get time expection in Unity. This is due to the following lines in the Update function in Unity (which I am not including in my code):
message = sp.ReadLine()
print(message)
This is causing Timeout Exceptions in Unity. To avoid this, I would suggest to:
- delete the ReadLine() command if it's not necessary for your use case
- use Try Catch syntaxt to deal with the error messages.
3. Play with both
Now, everything should be working. If you click on PLAY in Unity you are able to see the preview of the game and by clicking on each Sphere on Unity, you should see the LED lighting up on Arduino.
Code is available on GitHub.
Conclusion
This basic example can be used as a starting point. Once you know how to send the input to Arduino, this can be applied to more sophisticated application.
Reference & Useful Tutorials:
Hello There,
Thanks for this great tutorial.
I only need one more thing other than you are providing.
What do i need to do if there is a fourth sphere or a button on Unity side to turn all LEDs off when it is clicked as a master switch? Is there a quick and easy way to do this?
If you can help I would appreciate it
Thannk you
Necip