Connecting the EV3 and the Arduino

In this HowTo, we’ll show you how to get your EV3 and your Arduino to communicate, and how to use Arduino Shields with the EV3. The EV3 is much more powerful than the NXT, but at the time of writing this article, the software available is much harder to hack with.  We recently tried to make this easier by developing EV3 blocks for I2C communications.   In this post we’ll show you how to use the EV3 blocks to communicate with the Arduino and any shields you may want to add to the EV3.

We use a breadboard to break out the I2C lines in this example. You can use the NXT Breadboard adapter to break out the Mindstorms sensor cable to use the NXT cable directly without messing up the cables.  You can order  them on our website here, and on Amazon here.

EV3-Arduino (2)

In this tutorial, we’ll use the Arduino Uno to read and write data to the LEGO Mindstorms EV3. We’ll also demonstrate how to use the Arduino to read an analog values and send them to to the EV3. You can easily modify this to send or receive any kind of data to the EV3,   from accelerometer readings to geiger counter values.  This is probably the fastest way to add your own sensors and devices: when you connect the EV3 and the Arduino and the world is yours!

The EV3 and the Arduino can be made to talk over I2C.  In this tutorial, we setup the Arduino as an I2C slave, and the EV3 as an I2C master.

In this example, we show you how to send commands to the Arduino from the EV3 and how to write a program that requests data from the Arduino.

Background

I2C is called a “two wire interface”, because it uses two wires to communicate.  One LOGO For I2Cwire provides a clock: this makes sure that both devices are sending information at the same speed. The clock line is usually referred to as “SCL“. The other wire is for sending data (data is sent and received by both devices at the same time), and is usually referred to as “SDA“.  The master (always the EV3) always controls the communications, and always sets the communications clock for both devices.  The device being controlled is referred to as the slave. When the master sends a command, the slave drops everything and listens.  When the master demands information, the slave provides that information.

 

In this example, we did not have to use pullup resistors on the I2C lines.  However if the I2C is not working at all, you might have to use 47k pullup resistors on the SDA and SCL line to pull the I2C to 4.7V on the VCC line.

Setting up the hardware

First, a schematic of what we’re aiming for.  The schematic shows the EV3 plug on the left hand side of the drawing, and the Arduino on the right hand side.  We will need the Ground, VCC, SDA and SCL to be connected.

Arduino-and-NXT-Schematic

For the setup, we’ll wire together will look like this:  Ev3–> Breadboard –>Arduino. You can see an overarching view of everything below.

EV3-Arduino (2)

In this example, we’re going to connect only the SDA, SCL lines (for communications), VCC for powering the Arduino from the EV3 and the ground (GND) line to equalize the communication voltages.

Connecting to the Arduino:

First, place on jumper into a GND port on the Arduino. Place one jumper on A5 (SCL, the clock line) of the Arduino Uno, and one jumper on A4 (SDA, the data line). In the picture, you can see that we placed the Red jumper to VCC, Black jumper into GND, the Yellow Jumper into SDA (A4) and the Green jumper into SCL (A5).

EV3-Arduino (5)

Connecting to the EV3:

The easiest way to connect this up to the EV3 is to use the Breadboard adapter . Again, same colors go in the same spots: the Yellow wire in our example, is connected to SDA on the breadboard. Ditto for SCL and GND and VCC.

Just to clarify: SDA –> SDA ; SCL –> SCL.

You can hack together a custom adapter pretty easily: cut off one end of the standard EV3 black cord, and open up the wires. SDA and SCL are yellow and blue, while the gnd line is black and the red and the VCC is the green one.

EV3-Arduino (10)

In these pictures, the following colors correspond to these lines:

  • Black: Ground
  • Red: VCC 
  • Green: SCL
  • Yellow: SDA

On the Arduino Side, we will connect the SDA, SCL, VCC and Ground into the Arduino headers.

Software:

The software for the EV3-Arduino interfacing is divided into two parts. One is the Arduino sketch that goes on into the Arduino and the other is the LEGO MINDSTORMS EV3 Labview software on which the blocks are created which send and receive the data to and from the Arduino.

All the code can be downloaded and used from our Github EV3 repository.

Setting the Arduino up for I2C: Assigning an Address

In our Arduino examples, we have to setup a few things to get going.  We need to select a slave address.  In this example, we set the slave address to 0×04, which is hexadecimal.

Arduino As Slave Receiver/Sender:

In this example, the Arduino will receive data from the master.  The EV3 simply says “here’s some data” and the Arduino says “thanks for the data”.  This is a very simple setup and most sensors operate as a Slave Receiver and Sender.  This example can be really useful if you’re setting your Arduino up as a motor controller or for LED output.

In this example, the EV3 sends some data to the Arduino. The Arduino receives it and and prints it on the Serial Monitor. If the EV3 requests for some data then the Arduino sends it a byte. You can easily modify it to send or recieve any number of bytes. There are examples for 8 byte read/write in the Github Repository.

#include <Wire.h>
#define SLAVE_ADDRESS 0x04
void setup()
{
    Serial.begin(9600); // start serial for output
    Wire.begin(SLAVE_ADDRESS);
    Wire.onReceive(receiveData);
    Wire.onRequest(sendData);
    Serial.println("Ready!");
}
int val,flag=0;
void loop()
{
  if(flag==1)
   {
     Serial.print(val);
     flag=0;
   }
}
void receiveData(int byteCount)
{
    while(Wire.available()>0)
    {
      val=Wire.read();
      flag=1;
    }
}
// callback for sending data
void sendData()
{
  Wire.write(0x45);
}
Here the setup() functions starts the Serial and assigns the functions to be called when the data has to be sent to or received from the EV3.
The receiveData() is used to receive the data from the EV3 and the sendData() is used to send the data to the EV3.
Upload this sketch to an Arduino to use with the EV3 software.

EV3 as the Master

Setting up the EV3 as the master is simple. Download the Dexter Industries EV3 blocks (Dexter.ev3b) and Import them into the Lego Mindstorms EV3 Software (Tools ->Block Import).

Use the Dexter Industries I2C communication block iconto start communicating with the Arduino.
For a basic 1 byte read, just create the block sequence with Read 1 Byte block. Enter the Slave Address that we had used earlier, i.e., 0×04 in the Addr field and start the program to see the data from the Arduino coming and getting printed on the EV3 screen.
read_1_byte
For a 1 byte write, change the function to Write 1 Byte and enter the byte that you want to send to the Arduino. When you start the program, the EV3 will send the data to the Arduino and the Arduino will display the data on the Serial Terminal.
write_1_byte
Similarly, you can upload this sketch for 8 byte Read/Write and use the 8 byte Read/Write Functions to send or receive the data from the Arduino.
read_8_byte
Something very useful, could be fetching an analog value from the Arduino and sending it to the EV3. If you want to do that, upload the analog read sketch to the Arduino and start the EV3 program with an Analog Read Block. Specify the pin you want to read from and start the program and the analog values will start coming from the Arduino.
analog_read
That’s it for the EV3 -Arduino interfacing.  Let us know what you did with it!  If there’s anything missing or you need something clarified, just mention it in the comments or post it in the forums.