Back to L3DGE

Setting up a L3DGEWorld and Arduino environment

Chris Holman (IBL Student), Nov. 5, 2012.

This guide will provide a step by step tutorial in setting up both L3DGEWorld and arduino-l3dge, and creating a program that communicates between the two.

This tutorial has been tested with Arduino 1.0.1 on Windows 7 (i386) and FreeBSD 9.0-RELEASE (amd64).

For demonstrations of Arduino and L3DGEWorld, see l3dgecomm for Arduino.

To download arduino-l3dgecomm, see the L3DGEWorld tools page

Setting up Arduino

  1. Download and install the Arduino IDE.

    Arduino for Windows, Mac and Linux can be downloaded from the Arduino website. No installation is needed - simply extract the contents of the archive to a folder.

    Arduino for FreeBSD can be installed from the FreeBSD Port, devel/arduino, or a PC-BSD PBI.

    On FreeBSD 9.0-RELEASE, Arduino could not find the Java libraries. If you receive an error when starting Arduino about missing classes, add the line export JAVA_HOME=/usr/local/openjdk6 to /usr/local/arduino/arduino. The location of JAVA_HOME will change depending on which version of Java you have installed. We had OpenJDK 6 installed.

    The up-to-date port of avr-libc also had an incompatibility and had to be downgraded from 1.8 to 1.7.1 - as root, cd /usr/ports/devel/avr-libc && make deinstall . Then, download avr-libc-1.7.1.tar.bz2 from the avr-libc website. . Finally, tar -xf avr-libc-1.7.1.tar.bz2 && cd avr-libc-1.7.1 && ./configure --build=`./config.guess` --host=avr && gmake && gmake install clean. Do this if you get messages regarding 'poisoned SIG_USART' in HardwareSerial.cpp

  2. Connect your Arduino

    Connect your Arduino to a USB port in your computer. If prompted to locate drivers, they are located in the \drivers\ folder where you extracted Arduino.

  3. Test your Arduino

    Open the Arduino IDE software - the executable is located in the directory you extracted Arduino to. Important: if you are using FreeBSD/Linux/Mac, you may need to use sudo, kdesu or similar, or, add your user account to a group with access to the serial ports (dialer on FreeBSD)

    Once open, select the Tools menu, then the Board submenu. From the list, select the Arduino device you have.

    Again from the Tools menu, select the Serial Port submenu. If you know which serial port your Arduino device is connected to, select it here. (The Arduino uses a USB to Serial adapter internally, so will appear as a serial port. On FreeBSD, it will appear as /dev/cuaU*, not /dev/cuau* like a normal serial port)

    Test that it can be successfully programmed by uploading the following program to it:

    void setup(){} void loop() {}

    If everything is set up correctly, clicking the "Upload" button will compile the program, then send it to the Arduino device. If a dialogue box appears asking about which serial port to use, try each available serial port in turn until it works.

  4. Install arduino-l3dgecomm

    Download arduino-l3dgecomm from the L3DGEWorld tools page. Inside the archive, copy the l3dgecomm folder to the \libraries\ folder of your Arduino installation - that is, the folder you extracted Arduino to. Restart or open the Arduino IDE, and go to the Sketch menu, then the Import Library submenu, then ensure that l3dgecomm is in the list. Consider taking the time to read the README file inside the arduino-l3dgecomm archive, too.

    arduino-l3dgecomm also requires the Time library. Download and extract the archive also to the libraries folder, such that inside the libraries folder, there is a Time and a l3dgecomm folder.

Setting up L3DGEWorld

  1. Download and Install L3DGEWorld

    Download L3DGEWorld from the L3DGEWorld homepage. Extract the contents of the archive to a folder.

    Run the L3DGEWorld program to ensure that it works - there are shell and batch scripts for each of the operating systems. L3DGEWorld should open straight up to a map located in space, with four large platforms.

  2. Configure input and output daemons

    Your arduino will act as an input daemon, and possibly an output daemon. An input daemon sends data to the L3DGEWorld server, controlling how the entities behave in the L3DGEWorld world. An output daemon receives messages from the L3DGEWorld server, which are triggered by the user interacting with the entities in L3DGEWorld.

    When the Arduino device is programmed, it will need to be assigned an IP address. Decide now which IP address it will be assigned. For the purposes of this tutorial, we will assume it is 10.0.0.20, and the L3DGEWorld server is 10.0.0.10. Replace these addresses as needed. If the Arduino device is not on the same subnet as the L3DGEWorld server, you will need to modify the arduino-l3dgecomm library to use a gateway.

    In the L3DGEWorld installation directory, open the baselw directory. There are two files that we need to change. To allow the Arduino device to send input to L3DGEWorld, allowedinput.conf must contain the IP address of the Arduino. The file must end with a blank line.

    To send output ("actions") to the Arduino, the IP address and port must be the first line of outputip.conf. They are separated by a colon. For example, 10.0.0.20:27960. If you do not want the Arduino to be sent action messages, you do not need to modify this file.

Connecting L3DGEWorld and arduino-l3dgecomm - input daemon

Both the Arduino and L3DGEWorld are ready to talk to each other - now all that remains is the program to be made. For the input daemon, we will make a very simple program that reads the value of a voltage divider - in this case, a potentiometer - and sets entity 1 to spin according to the value read. We used a 500kΩ potentiometer, but any potentiometer will work fine, as long as the minimum resistance is above a few hundred Ohm.

  1. Wire up the input

    The potentiometer has three pins in a row. The two outer pins are either end of a resistive wire, and the middle pin is connected to a movable contact that moves along the resistive wire. This forms a voltage divider.

    Connect one outer pin to the GND or 0V pin, the other outer pin to the 5V pin, and the centre pin to analog input pin A0.

  2. Connect the Arduino

    Connect the USB cable between the PC and the Arduino. Connect the ethernet cable to the Arduino and either a switch or the PC - if the latter, use a cross over cable.

  3. Program the Arduino

    First, go to the Sketch menu, then the Import Library submenu, and select:

    • l3dgecomm
    • Time
    • Ethernet
    • SPI

    Then, we code. Start by defining a few global variables:

    // Randomise this a bit - it's the MAC address of the Arduino byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xF9, 0xFF }; // This is the IP address of your Arduino IPAddress ip (10,0,0,20); // This is the IP address and port of your L3DGEWorld server IPAddress l3dgeIP (10,0,0,10); unsigned int l3dgePort = 27960; l3dgecomm * L;

    The setup() routine of the program needs to initialise the ethernet and l3dgecomm.

    void setup() { Ethernet.begin(mac,ip); L = new l3dgecomm(l3dgeIP, l3dgePort); }

    The loop() routine must send the l3dgecomm update message, then check for any waiting packets.

    void loop() { char[20]; unsigned int entityId = 1; Action * act; // Assemble the update message! sprintf( buf, "%i", analogRead(0)/10 ); // Send the update message L->sendUpdate( entityId, L3DGE_METRIC_SPIN, L3DGE_FIELD_RATE, buf); // Check for incoming packets while ( act = L->checkPackets()) continue; delay(100); // 1/10th second }

    This simple program is now ready to send data to L3DGEWorld. Make sure that you changed the IP addresses according to your local environment.

    If you click "Upload", it will program the Arduino. Once it has uploaded. open L3DGEWorld, then press the reset button on your Arduino device. Turning your potentiometer should now alter the spin rate of the first entity.

    Connecting L3DGEWorld and arduino-l3dgecomm - output daemon

    Very few changes to the code are needed to have the Arduino act as an output daemon. First, some global variables must be initiated.

    // How many outputs you wish to use. // Note that the Ethernet shield uses digital pins 4,10 int numOutputs = 4; int outputPins[ numOutputs ];

    All of the pins need to be initialised. In the setup() function, put the following:

    int i; for (i = 0; i < numOutputs; i++) { pinMode(i,OUTPUT); digitalWrite(i,LOW); outputPins[ i ] = LOW; }

    Inside the loop() function, we need to check for any incoming action messages. - all we need to do is perform an action when act is not null. The act variable is an Action struct, which contains an entityId, toolId and a string of the metric values. If act is not null, perform an action based on its contents.

    For our example, we will toggle a digital port according to which entity ID the action was triggered on. Accordingly, we alter the while loop with the following:

    // Put this line at the start of loop() int pinId; while (act = L->checkPackets()) { pinId = act->entityId - 1; if (pinId < numOutputs) { if (outputPins( pinId == HIGH) { digitalWrite( pinId , LOW); outputPins[ pinId ] = LOW; } else { digitalWrite( pinId, HIGH); outputPins[ pinId ] = HIGH; } } }

    Connect an LED and a resistor in series to a digital port with an ID less than numOutputs (above), then shoot the entity in L3DGEWorld with an entity ID that corresponds to the digital port, and the digital port should toggle on and off. For example, shooting entity #2 in L3DGEWorld should toggle digital port 2.

    It is important to note that the Arduino Ethernet Shield reserves a few ports, and altering their state can cause the shield to stop working. Digital ports 4 and 10, as well as some board specific pins. See the Arduino Ethernet Shield page for more information.

    The value of the resistor to use depends on which colour LED you are using - try between 100Ω to 500Ω until you are happy with the brightness. See this handy calculator to get an exact value (use the question mark boxes next to the input fields). The source voltage is 5V.

    Additional notes

    At this point, you should have information flowing in both directions - from the real world (potentiometer) to L3DGEWorld (spinning entity), and from L3DGEWorld (shooting an entity) to the real world (toggling an LED).

    The README file within the arduino-l3dgecomm archive contains important information about how to expand upon this basic tutorial, such as the Action struct, constants available for use and other l3dgecomm functions.

    To create a custom map to represent your data, follow the Map & Entity Modelling for L3DGEWorld guide. In step 2 of Installing and configuring GTK Radiant (for windows), after you have extracted the howto-mapping.rar archive, you should rename the \GTKRadiant 1.5.0\oa.game\l3dgeworld\ folder to baselw, or whatever the l3dgeworld mod folder is called within your L3DGEWorld installation directory.