High School

LEGO Education "Sound Block" Video

The link below provides LEGO Educations' "Sound Block" video for the EV3, which includes the Sound Editor:


LEGO Education "Display Block" Video

The link below provides LEGO Educations' "Display Block" video for the EV3, which includes the Image Editor:


LEGO Education "Action/Flow Palettes" Videos

The links below provide LEGO Educations' "Action/Flow Palettes" videos for introducing basic programming for the EV3:

Introducing Palettes:

The Motor Blocks:


This course is intended to introduce the Java programming language to students using the EV3 (FLL), Tetrix (FTC) and RoboRio (FRC) robotics platforms. For EV3, the course moves the student away from block based robot programming to using an advanced text based programming language. For Tetrix and RoboRio, the course will provide more instruction in Java itself, which is missing in existing materials. The course will teach a basic competency in Java with a focus on robotics applications. Robot construction will not be covered in any depth as it is assumed the student will have or acquire hardware building skills separately.

Get started using this course by clicking the first Unit and then the first Lesson. The Lesson content will be displayed and next/previous lesson buttons will appear at the bottom of each lesson making it easy to move between adjacent lessons.

Education Level: 
Explore Pneumatics, what it is, how it is used and programmed on FRC robots.

Gain a basic understanding of Pneumatics and how it is used and programmed on FRC robots.


Pneumatics is a branch of engineering that makes use of pressurized gas to control physical systems. Pneumatics are used extensively on FRC robots using compressed air to create mechanical motion. The FRC pneumatic system is comprised of an air compressor, air storage tank(s), pressure sensor, relief valves, regulator, tubing, control valves, cylinders and the Pneumatic Control Module (PCM). The objective is to create mechanical motion using cylinders that produce push and pull motions in response to air pressure directed to them via valves controlled by your robot program.

The PCM is the key component of the pneumatic system. It controls the compressor motor and the valves that direct the air to cylinders. The compressor is controlled by a pressure switch (connected to the PCM) and a relief valve that limits pressure on the compressor/storage tank side of the pressure regulator to 120 pounds per square inch (PSI). The relief valves are manually set and open on their own when pressure goes over 120psi. The pressure switch turns on below 120psi and turns off at 120psi and is used by the PCM to turn the compressor on and off with the goal of keeping 120psi on the supply side of the pressure regulator. The purpose of the relief value is to prevent over pressure if the pressure switch fails to turn off the compressor at 120psi.

The pressure regulator separates the air supply side (compressor and storage tanks) from the working side (valves and cylinders) and sets the pressure on the working side to 60psi. These pressure settings are defined in the FRC rule book. From the working side of the regulator, air is directed to control valves. These valves are connected to the PCM and are controlled by your program. You determine when to open and close the valves. The valves direct air to cylinders where the air pressure causes the cylinder shaft to move in or out.

Cylinders, and the valves that control  them come in two types: single action and double action. Single action cylinders have a spring that retracts the shaft when air pressure is not present. When air is applied, the shaft moves out and remains out as long as pressure is applied. When pressure is removed the spring retracts the shaft. Single action cylinders have only one air input port. Single action cylinders are controlled by single action valves. Such valves have one input port (air from regulator) and one output port (connected to the cylinder) and one set of wires which connect to a valve port on the PCM. The valve opens when power is applied and has a spring that closes the valve when power is not applied. Pressure is only present at the cylinder when the valve is open. When the valve is closed, the output port connected to the cylinder is vented to the atmosphere allowing air in the cylinder to escape.

Double action cylinders have two sets of input ports and no spring. In this case you apply air to one port (and open the other port to the atmosphere) to move the cylinder shaft in one direction (in or out). You apply air to the other port to move the shaft in the opposite direction. The shaft stays in either the in or out position as controlled by a double action valve. The double action valve has two output ports, one for each of the ports on the cylinder. You can think of valve as having a sliding gate inside of it that moves one side to the other and applies air pressure to one output port or the other. When air is not applied to an output port, that port is vented to the atmosphere. Your code moves that sliding valve from one side to the other to change which output port the air pressure is applied to causing the cylinder shaft to move in or out. Pressure is always applied to one side or the other when there is pressure in the system. The key is that double action cylinders stay in or out until you change the setting of the valve. Note that double action valves have two sets of wires and take two ports on the PCM.

The valves that control the air have mechanical and electrical components. The electrical side consists of one or two solenoids. A solenoid is a magnetic actuator that translates an electrical signal into mechanical motion. You apply power to a solenoid on an air valve and valve opens (typically moves a slider that connects the valve output port to the pressure input port). The WpiLib provides a Solenoid class for your use in your programs to control air valves. For a single action valve you create a single solenoid object to control that valve. When you create the object you provide the CAN id of the PCM and the port number on that PCM that the valve is connected to. In your code to use the set(true/false) method of the Solenoid object to apply power (true) to the valve to open it.

A double action valve is more complicated. It has two solenoids, each one causes the sliding valve to move to one position or the other. So you need to create two solenoid objects in your code, one to apply air pressure to one side of the valve and one to apply pressure to the other side of the valve. You only need to apply power to one side or the other to move the valve to that side. Note that you must apply power for a period of time,  typically .05 seconds to allow time for the physical valve (slider) to move to change the setting of the valve. After moving the valve you can turn off the solenoid power (removing pressure) as the valve will stay in the new position. Double action valves take two ports on the PCM. Double action valves typically have thier sides (solenoids) marked as A and B. A wiring convention is the A side is wired to the first of the two PCM ports and should represent "opening" the valve. The B side is wired to the second PCM port and represents "closing" the valve. You would then plumb (do the air tubing) the valve to connect the A output port to the input port on the cylinder that causes the shaft to extend (open) and the B output port to the other input port on the cylinder to cause the shaft to retract (close).

In your code, when you create solenoid objects to double action control valves, you need to set the initial position of the valve at start up so that your cylinders start in the correct position (extended/retracted).

Due to the potential danger presented by the pneumatic system stored air pressure, there are strict rules in the FRC rule book governing the components of the system and their layout. You need to pay close attention to the rules when constructing your pneumatic system to make sure it complies with the rules. Your robot will be inspected at competitions and you will be required to fix any part of the system that is outside the rules. You should review the rules every year as the rules may change in subtle ways and make sure you are using approved part numbers for your pneumatic components.

Here is a detailed discussion of the pneumatic system. Here is wiring documentation. Note that there are rules in each years rule book that supplement this documentation.

Operation of the valves provides a great oppourtunity to show how you can simplify your programming by putting complex or often used code into classes. It makes sense to create classes to contain the details of operating the air valve solenoids and present a simple open/close interface to the rest of your code. Here are two sample classes that handle the single and double action air valves:



Explore the sensors used on the FRC platform and the basics of how they are programmed.

Gain a basic understanding of the sensors available on the FRC platform and how they are programmed.


Sensors are hardware devices used to gain information about the robot environment or operation. There is a large number of devices available as FRC can use any device in the world as long as you can interface it to the RoboRio. We are going to discuss some of the commonly used ones.

Limit Switch. Limit switches are simple mechanical devices that are used to sense mechanical motion. The limit switch has an arm on it that is contacted by some moving part of a robot and the switch returns a true/false indication. You use the WpiLib DigitalInput class with limit switches which are wired to RoboRio digital input ports.

Hall Effect Sensor. A Hall Effect sensor is similar to a limit switch but does not physically contact the moving robot part. You mount the sensor on a fixed part of the robot and a magnet on the moving part and when the magnet passes close to the sensor it will report that in the same way a limit switch would. Use the DigitalInput class and wire to a digital input port.

Encoder. An encoder is a device that you attach to the end of a rotating shaft to measure the revolutions and direction of that shaft. Use the Encoder class and wire to a digital input port. Note that encoders may need two ports to sense direction or increase resolution. Typically used to determine how far your robot has travelled.

Magnetic Encoder. Same as an encoder but senses a magnet on the shaft instead of using a physical connection.

UltraSonic Distance Sensor. Uses ultrasonic sound waves to measure distance to an object. Use the UltraSonic class for some sensors and the analog input class for others.

Light Sensor. Measures light falling on the sensor. There are forms of the sensor that you connect to a digital input port and the sensor acts as an on/off sensor and there are forms that return a measurement of the light and you would use an analog input port to obtain the light reading.

Gyroscope. Measures change in direction of travel of a robot. Use the AnalogGyro class and connect the Gyro to analog input port 0 or 1 (these ports specifically know how to handle gyro input).

Camera. A hallmark of FRC competition and engineering is the use of computer vision. Every game has a vision target of some kind in the game. You can use cameras connected to the RoboRio to collect images and then process those images to locate the target. With that information you can navigate your robot as appropriate. Vision processing is a large and complex subject with different ways to implement it. There is quite a lot of information available online. We expect to add a vision processing lesson during the 2017 season when the new Grip vision processing system is released to teams.



Explore the use of logging to debug robot programs.

Understand logging and how to implement it in RoboRio based robot control programs.


We are now going to take a look at logging (also called tracing) as a tool to debug our robot programs. Logging is recording useful information from the robot program to a disk file on the RoboRio controller. You can then download that file to your PC and examine it. It can be very useful to record information while your robot is running during a match so you can look at it afterwards and see what took place. If you have not read the general lesson on Logging, you should do that now.

Note that the FRC control system supports using System.out.println to write information to the RioLog and to the session log on the Driver Station. However these two ways to log information have drawbacks. The RioLog does not persist and is not available during match play. The DS log also contains extensive logging from the control system and it can be hard to separate out your logged information. Niether form of logging provides automatic identification of where in your program the logged information comes from. The logging code provided here automatically marks all logged information with the date, time, name of method and location in your source file where the information was logged. Only your logged information is recorded. The information is recorded in a new disk file for each startup of the RoboRio and can be easily downloaded after sessions or matches for review. Note that the logged information is also sent to the RioLog and the DS log.

To use the Logging class below with the Sample robot program, create a new class called Logging in the same place as Robot.java. Copy and paste the code into that class.

Now you can modify the Sample program as follows to use logging instead of System.out.println():

You can view the log file on the RoboRio disk with a browser. Navigate to ftp://roborio-nnnn-frc.local/home/lvuser and select the desired log file. You can download the log file with Windows Explorer. Navigate to the url <to be inserted> and copy the desired log file to a local directory.

Note: Log files are numbered 0-99. After 99 no new log files will be created and an error will be logged to the DS console window. You must use Windows Explorer to delete old log files.



Explore the Sample Robot source code in more detail.

Understand in more detail how the Sample Robot project works and how you can expand it to do more.


Lets examine the Sample Robot project in more detail.

Looking at Robot.java the first thing we see is the package created for us by the WPILib plugin based on our team number.

Next we see some reference variables defined. These are for a RobotDrive object and a Joystick object. These objects are part of the WPILib API. The RobotDrive object gives you many ways to control the motors in a robot drive system.  The Joystick object gives you access to the inputs (deflection and buttons) available from a joystick.

Next we see the Robot class constructor. Here we initialize the myRobot and stick variables to instances of their classes and specify the port numbers these devices are attached to. In the case of the myRobot instance, the motors are assumed to be plugged into the RoboRio PWM ports 0 and 1. For the stick instance, it is assumed to be plugged into a driver station USB port and mapped to port 0 in the driver station app. This initialization could be performed in the robotInit() method and that is probably the best place as there are minor differences between the constructor and the robotInit() method.

After the constructor is completed, the robotInit() method will be called. In our example we have nothing to initialize in that method so nothing happens.

After the robotInit() method completes, the disabled() method is called as the robot is considered to be in the disabled state right after your code is loaded. disabled() is also called when either autonomous or operatorControl periods end. Here you would have code to make sure your robot is in the correct state and prepare for transition to the next mode.

The autonomous() method is called when the autonomous period is started. In our example we do a simple drive forward by using a method of the myRobot object (myRobot.drive) to set motor power (this particular method sets both motors) to 50% with no turn angle. This will cause the motors to turn on. We then wait for 2 seconds and then call the same myRobot.drive method to turn the motors off. We then exit the method and that is the end of our autonomous function. Note that the minus sign on the myRobot.drive power argument. Plus and minus indicates forward and backward. Forward and backward are relative to the robot, motor and gearing design of the robot and will need to be determined experimentally. The example assumes minus turns the motors so the robot moves in the forward direction. 

The operatorControl() method is called when the teleop period is started. In our example, we want to use the joystick to drive the robot in arcade (one joystick) style. We use the arcadeDrive() method of the myRobot instance of the RobotDrive class to do the driving. We pass the stick instance variable directly to the arcadeDrive() method and it will get the joystick deflection and set the motor speed and direction for us. We want to continue driving so we wait a short time before looping back and setting the motor power again. We want to keep doing this until the teleop period is over, so we condition the while loop by looking at two methods that are available to us from our parent SampleRobot object. The isEnabled() method returns true if the robot is enabled and we also check the isOperatorControl() method to make sure the period has not changed. Note that if our autonomous code might run to the full time of the autonomous period, we need to employ these same kind of checks (using isAutonoumous) to make sure our code stops when the period is over.

Further note that the wait function we use is Timer.delay(.020). Timer.delay is a special wait function that will stop our code but not interfere with motor control activities. We select 20 milliseconds because that is approximately how fast the joystick data updates are sent from the DS to the RoboRio.

The last thing we want to look at is Motor Safety. The RobotDrive class has a built-in feature that is intended to prevent runaway robots. This is called motor safety. A timer is automatically started on a RobotDrive object and if there is no input supplied to the RobotDrive instance in the time allowed, the motors associated with the RobotDrive object will be stopped. In our example we set the timeout to 100 milliseconds which should be good as we plan to update the motor power setting every 20 milliseconds. If our code crashed or looped and we failed to update the myRobot instance for 100ms then our motors would be stopped.

Note that in autonomous mode there is no joystick so once we set power in this example, there is no further motor input for our 2 seconds of run time. Obviously the motor safety feature would stop our robot, so we turn motor safety off for the autonomous period. But this does mean you have to be careful with your code as there is no runaway protection. When we go to the teleop period, we make sure that motor safety is turned back on. When I said no runaway protection, I meant automatic protection. The DS disable button will stop a runaway robot, so when testing your code you should always be ready to click the disable button if things go wrong.

Note that we use System.out.println to implement a simple execution trace. The println output goes to the RoboRio console. You can view this console output using one of the console viewers.

That completes our review of the Sample Project. Obviously a real robot would have more functionality and more physical hardware to control. We will look at more complex examples next.

Here is the top level of the Java specific on-line documentation. 

Here is the detailed documentation of the Robot API classes contained in the WPILib for you to use.

Additionally, the attached PDFs contain valuable documentation and examples even if they are a bit dated.

To really program the RoboRio control system, you will need to read and be familiar with the information in these resources.



Explore the details of using Java to program the RoboRio control system.

Understand the different programming models used with the RoboRio control system. Understand the model we will be using in the following lessons. Understand how to create a new Java project for the RoboRio and how to compile and deploy it to the RoboRio.


RoboRio based robots can be programmed with one of three models or styles of program design. These are:

  • Iterative
  • Command
  • Sample

You can read a discussion of the three models here, but for our lessons we are going to use the Sample (also called Simple) model. It is our belief that this is the easiest model to start with.

All of the models use the idea of extending a base class that is part of the WPILib. This is similar to the FTC/Tetrix model. Your program has no main method, the main method is part of the WPILib program that runs on the RoboRio and hosts your program. Your program will consist of at least one class that extends the base class of the programming model you are using. Your class will override specific methods in the base class that will be called by the WPILib hosting program to start, stop and select the mode (autonomous/teleop) of your code.

The FRC competition match has two timed periods (or modes), autonomous and operator Control or teleop. In autonomous, your robot must accomplish tasks without any human input. In teleop, your robot is under human control via joysticks or other input devices.

Lets go ahead and create your first RoboRio Java program to see what this looks like. Start Eclipse and open the Window pull down menu. Select Preferences. On the Preferences dialog select WpiLib Preferences. Enter your team number (1111 for our sample) and save. Next open the File pull down menu. Select New, Project, Robot Java Project (under WPILib Robot Java Development). This will start a new project dialog. In the next screen give the project the name "Sample Robot" and select the Sample Robot model. Click next to create the project.

Once the project is created, navigate the project tree to the src directory to the package directory and finally to the Robot.java source file. The package is automatically generated by the plugin. Double click to open the file. This is the robot source code created by the WPILib plugin. However, we are not going to use this file as it is. It is useful to have the project created as described above because the project files have a number of customizations for deploying the code to the RoboRio. However, the sample code that is created for you is not what we want to use for our lesson. Here is a basic robot control program:

Select all of the code and copy it. Then go to Eclipse and select all of the code in the Robot.java file below the package statement (keep your package). Paste the code you copied from the .txt file into the Robot.java file in Eclipse replacing all of the original code below the package statement. Now we have the source code for the Robot class (for this lesson) we are using to extend the SampleRobot class from the WPILib.

We can now explore the Sample Robot project source code. As you can see, we create a class called Robot that extends SampleRobot. Our code will override the methods of SampleRobot to implement robot control. We will provide custom implementations of these methods:

  • robotInit()
  • autonomous()
  • operatorControl()
  • disabled()
  • test()

The robotInit() method is called once after the WPILib host has loaded your class and all initializations needed by WPILib are completed. It is here that you can perform any needed setup or initialization of variables or classes. In our simple example, there is nothing that is needed. Note we initialized the hardware items (motors and joystick) in the Robot class constructor. We could have done this in robotInit() as well.

After robotInit(), disabled() is called, because that is the start-up state of our robot. disabled() is called whenever the robot is disabled by the driver station or the field control system. When switching from autonomous mode to teleop() mode, disabled() will be called in between because your robot will be in the disabled state for some period of time between the periods.

When the autonomous period starts or autonomous mode is enabled from the DS, the autonomous() method is called. Your code that executes your autonomous functions will be placed in this method. Your code should remain in this method until your autonomous activities are completed or until the autonomous period ends.

When the operator control or teleop period starts or teleop mode is enabled from the DS, the operatorControl() method is called. Your  code that executes your driver controlled functions will be placed in this method. Your code will remain in this method until the teleop period ends.

The test() method can be initiated from the DS and is used to test your code. We will discuss the test() method later.

Once you have a program ready to compile, click the green arrow button on the toolbar. This will start the compile or build process. If there are no errors, the WPILib plugin will attempt to connect to the RoboRio and download (deploy) your program. A console log will open showing the results of the compile and download. Here is more information on the build/download process.

Note that downloading a program assumes you have connected your PCs wireless network to the robot network created by the robot wireless router. If your program downloads successfully, you can test it with the driver station.

With FLL or FTC robots it is pretty easy to throw together a test robot you can use to test your programming skills. This is not the case with FRC level robots. While your team may have a test robot for use as a testing platform, it may be that you will not be able to test your code until the robot for the current competition season is far enough along to be at least partially operational. There are some simulation tools available and discussed in the on-line documentation but we will not be covering simulation here.

In our next lesson we will discuss the Sample Robot project in more detail.