Edited by royal_Panic, forked from this blog post by Ethan Hansen.
If you're here you've probably looked up something like, "i2c Arduino to RoboRIO," on Google, then become frustrated with the lack of helpful responses. This is a step by step guide on how to wire together your Arduino and RoboRIO, then how to program it. This will not be an explanation of how the technology works. There are plenty of those out there. That being said, it is my opinion that if you copy someone else you should at least understand what is going on, so there will be broad, general explanations of why things are wired or programmed the way they are. I hope this saves you some tears.
- 1 Computer with the Arduino IDE.
- 1 Male to Female PWM (also called 3-wire) cable.
- 1 Arduino UNO (That's the one I'm using. I'm sure others will work, but this is the easiest).
- 1 RoboRIO.
- 1 fully connected electronics board (Not so much necessary as nice to have).
- 2 18 gauge wires.
On your Arduino there should be two pins that say "SDA" and "SCL". They are nearest to the USB port. Find them, then continue when you are ready.
Oh, you're already ready? Next, find the I2C pins on the RoboRIO. There is a whole section just for them. This is where the MtF PWM cable comes into play. Go ahead and stick the cable in so that the SDA pin on the Arduino is connected to the SDA pin on the RoboRIO and the SCL on the Arduino is connected to the SCL on the RoboRIO. There should be one pin on the wire that doesn't connect to the Arduino. That can just hang off to the right of the SCL pin and the other end can go into the 3.3v pin on the RoboRIO.
We are going to be powering the Arduino from the voltage regulator module (VRM). If you don't have an electronics board hooked up and don't know how head on over to https://wpilib.screenstepslive.com/s/currentCS/m/cs_hardware/l/144971-wiring-the-frc-control-system.
Take one of the very small wires and plug one end into a red 12v 500mA port on the VRM. The other end of that wire goes into the VIN pin on the Arduino. The other wire is the ground wire and goes from the black port next to the red one on the VRM to either of the ground (gnd) pins on the Arduino.
SDA is the line for Serial Data and SCL is the line for the Serial Clock. Tutorials on how to use I2C will say you need a pull-up resistor, but don't worry the Arduino already takes care of this. They will also say that you need to have a common ground across devices, and I spent quite some time worrying about that. If you have your ground for the Arduino in the VRM you should be fine. Another thing you don't have to worry about is the voltage and amperage going into the Arduino. It is recommended that the Arduino take between 7 and 12 volts and 500mA is enough margin for the Arduino to work with.
I'm going to be entirely honest. I tried to write my own code to send the data to the RoboRIO. I started in October. I was able to get the RoboRIO to talk to the Arduino, but could not for the life of me get the Arduino to talk to the RoboRIO. I probably spent 20 hours working on it myself and crying myself to sleep. I finally gave in and used someone else's code. Many, many thanks to redditor garrett7621 who's code works perfectly. His code can be found here: https://github.com/FRC5188/ArduinoPixyAndRoboRIO
However, his code was sending the x, y, and size values for the blocks detected by the camera and I just wanted the x values, so I took out the lines that were unnecessary. This code will set up the Arduino as the slave and the RoboRIO as the master, which just means that the RoboRIO is the one controlling when the data is sent.
The basis for this code also came from garrett7621, but with my own checking code. I am programming in command-based java, but I'm sure the difference from C++ is minimal. If you want you can copy and paste my code from https://github.com/EthanHans3n/BunnyBots-2017/blob/master/src/org/usfirst/frc/team4043/robot/commands/GetI2C.java
The other option is to use garrett7621's code and edit it to be your own.
The Arduino code is documented very well, so this will just explain the RoboRIO code.
The first thing is that this is a command, which means we will be calling it elsewhere to run it. For me, that was in autonomous code (Found in Robot.java).
The first thing to do in the code is to create an I2C object. We'll call that "Wire". Next, we define the maximum number of bytes that could be transmitted. We probably won't ever use 32 bytes, but it's nice to have some elbow room. Now we make a function called getData that will return a double. We need to have a "buffer" array to hold the incoming data, which we will call "data". Now we are reading from the slave device, the Arduino and writing the result into data. A byte array isn't particularly useful in this case, so we'll go ahead and change it into a string. The next two lines I don't know what they do, and I just copied them from garrett7621. I can tell they are cutting the string down at a specific place, but why or where I do not know. Now my code begins. Initially the code just looked like this:
if (realOut == "none") {
return 0d;
} else {
return Double.parseDouble(realOut);
}
This just says if there wasn't an object detected, return 0 as a double. Otherwise, change the string that you received into a double. I needed a double because the Arduino sends a value between 0 and 1. However, I was getting an error when it tried to return a 0, so I added the try - catch block to catch the exception and just return a 0 anyway. It worked, so don't knock it. The rest of the code in the command is just autogenerated basic stuff.
Credits: