HVM for the Arduino Uno

You can use the HVM to program the Arduino Uno using Java and Eclipse. It works the exact same way as with the EV3 (see below), the only difference is that you should choose the HVM Arduino Launcher instead of the EV3 or BeagleBone launcher. You must install the avr-gcc compiler and avrdude tool to cross compile and download to the arduino. How to install these tools is described many places, e.g. here. The HVM plugin requires these tools to be in your path and will automatically invoke them as needed. A minimal program blinking the Arduino LED in Java uses approx 8 kB of flash. This is including the HVM interpreter. The example below uses hardware objects to blink a LED on the Arduino board. No IP address is required since code is downloaded directly over the USB line.

Arduino Uno support has not been thoroughly tested. Log your findings at the Forum, if something is not working. The Java Heap has been preconfigured to 1 kB, so be careful with how much your program allocates.

 

HVM for the EV3 from Lego

You can use the HVM to program the EV3 from Lego using Java. See here how to download and install the HVM. A C cross compiler for the EV3 is also needed - details about installing a cross compiler is described elsewhere, e.g. here (Linux users) or here (Windows users, only step 1, 2 and 3 required). After installing the tools above, create a Java project with at least one class containing one main method - e.g. this example. In the eclipse project explorer expand the Main class and right click on the main method. Select from the drop down menu the 'Icecap tools' entry to convert the Java project into an EV3 application. The program must be free from errors before attempting a conversion. If some imports cannot be resolved add the icecapSDK.jar package to a folder in the project and include icecapSDK.jar in the project build path. Upon succesfull conversion a new view will appear showing the classes and methods in the application. Right click anywhere in this view to select another folder for intermediate files than the default one. This folder contains autogenerated C files that is used when launching the application.

To launch the application to the EV3 from Eclipse, click the 'Run' menu and select the 'Run Configurations' entry. A new window will appear in which the user can create a new HVM EV3 launcher and fill in some simple information:

 

  1. Source folder: The folder for intermediate files used above.
  2. EV3 IP Address: How to give your EV3 an IP adress is described many places on the internet - e.g. here. You only need to give the EV3 an IP address, you do not need to log in to the EV3. As soon as you have the IP address, enter it and select 'Apply' and launch the application by clicking 'Run'.

Console output is routed back to the host PC and displayed in the Console view in Eclipse. After the initial launch the application can be relaunched from the EV3 device menu. Select the 'run_program' program. Debugging is also supported.

 

Upgrade your EV3 device to the latest Lego firmware first. This is done automatically the first time you plugin your EV3 while using Lego's official software.

 

You do not need to flash any special firmware on the EV3. The HVM works with the official Lego firmware. You do not need a micro SD card.

 

Feel free to ask a question at the Forum if you run into trouble.

 

The HVM also supports the BeagleBone Black

You can also use the HVM to program the BeagleBone Black using Java and Eclipse. It works the exact same way as with the EV3, the only difference is that you should choose the HVM BeagleBone Launcher instead of the EV3 launcher. You can use the same cross compiler as used with the EV3. Connect the BeagleBone to your PC using the USB cable - this will (on Linux systems) give the BeagleBone an IP address.

To control input/output on the BeagleBone, native C methods can be used. Required native functions can be added to the file natives_beaglebone.c which is located in the output folder. First create and call the native method in Java space and relaunch the application. This will result in a linker error, from which it can be inferred what function name the HVM expects you to implement. More information about native methods are available here.

 

Other similar Java environments

There are other Java environments that support Java for low resource embedded platforms (in the kB range of RAM):

  • The KESO VM

    KESO compiles Java Ahead-of-time into C. It produces very efficient C code. Has some other interesting features as well. More about that on their web site.

  • The Haiku VM

    The HaikuVM is interpreter based. It is specifically developed for AVR microcontrollers.

  • The uJ VM

    The uJ (micro-J) VM is also interpreter based.

Drop a comment at the forum if you know of any other Java execution environments that can run on low resource embedded devices!

 

A Java for the Arduino Uno example

package arduino;

public class Arduino {

	public static native void delay_ms(short i);

	public static void main(String[] args) {
		Port p = new Port(0x20);
		p.DDRD = 0x20;
		while (true) {
			p.PORTD |= 0x20;
			delay_ms((short) 400);
			p.PORTD &= ~0x20;
			delay_ms((short) 400);
		}
	}
}
      

 

A Java for the BeagleBone example

package main;

public class HelloWorld {

	public static void main(String[] args) {
		for (int i = 0; i < 20; i++)
		{
			devices.Console.println(i);
		}
	}
}
      

A Java for the EV3 example

package main;

import devices.ev3.EV3;
import devices.ev3.Motor;
import devices.ev3.MotorPort;
import devices.ev3.SensorPort;
import devices.ev3.UltraSonicSensor;
import devices.ev3.Motor.Direction;
import devices.ev3.MotorPort.MotorPortID;
import devices.ev3.SensorPort.SensorPortID;

public class Main {

        public static void main(String args[]) {
                testMotor();
                testSensor();
        }

        private static void testSensor() {
                SensorPort port = new SensorPort(SensorPortID.Port1);
                UltraSonicSensor ultraSonicSensor = new UltraSonicSensor(port);
                for (byte x = 0; x < 30; x++) {
                        short sensorValue = ultraSonicSensor.getSensorValue();
                        devices.Console.println("value = " + sensorValue);
                        EV3.sleep(500);
                }
        }

        private static void testMotor() {
                MotorPort port = new MotorPort(MotorPortID.A);
                Motor m = new Motor(port);
                m.setPower((byte) 20);
                for (byte x = 0; x < 3; x++) {
                        if (x % 2 == 0)
                        {
                                m.setDirection(Direction.FORWARD);
                        }
                        else
                        {
                                m.setDirection(Direction.BACKWARD);
                        }
                        m.start();
                        EV3.sleep(1000);
                        m.stop();
                        EV3.sleep(1000);
                }
        }
}
	
      

Some more EV3 examples:

  1. StopAtWall.java