
Java ME Embedded on Raspberry Pi

As far as I can tell, on Habré and not only, there is a surge in interest in microcontrollers - devices based on ARM processors and other unusual hardware. The market responds symmetrically. To meet the demand, Arduino, Biggle Board, Raspberry Pi and many other useful gizmos appeared.
Nothing has passed since the beginning of this year, and two articles appeared on Habr at once about using the Java platform on the Rasprerry Pi "Raspberry Pi and a cup of Java, please!" and “Raspberry PI and JAVA: A closer look”. Naturally, the experiments used the familiar Java SE, whose port under ARM appeared about two years ago. Few people know that Java ME did not rest in peace with the era of Nokia push-button phones. She lives a full life in the new world - the world of embedded systems. Today I want to talk about the application of Java ME on the Raspberry Pi.
Oracle Java ME Embedded is a full-fledged Java runtime, optimized for devices with ARM architecture and systems with limited hardware capabilities. Java ME shows itself in all its glory on platforms with weak computing power and small RAM resources that work with network services. For example, such as wireless modules, positioning modules, smart resource meters, environmental monitoring sensors, vending machines, telemedicine, and, of course, smart homes.
Using Oracle Java ME in your projects provides a number of interesting features. Firstly, the main advantage of Java - “write once, run everywhere” now works in the case of embedded devices. Secondly, the platform integrates the application lifecycle management system and its remote update on the device (AMS - application management system). Thirdly, you get a special API for access to peripherals (DAAPI - Device Access API). Fourth, free development tools, which are rare for embedded systems (Java ME SDK for NetBeans and Eclipse). As well as a set of standard services integrated into the platform: File I / O (JSR 75), Wireless Messaging (JSR 120), Web Services (JSR 172), Security and Trust Services Subset (SATSA - JSR 177), Location (JSR 179), XML (JSR 280).

Oracle Java ME Embedded Product Stack
As you already understood, Oracle Java ME Embedded is a cross-platform product and supports a number of devices with ARM architecture. The current release version of Oracle Java ME 3.3 is 3.4. The platform is ported to Cortex-M3 / RTX (KEIL Evaluation Board), ARM11 / Linux (Raspberry Pi Model B), ARM9 / BREW MP (Qualcomm IoE development), X86 / Windows (emulator). The following are reference platform implementations released by Oracle. It is possible to port the platform to other devices in the event of such end-user needs.
Officially, the smallest possible configuration of Oracle Java ME Embedded requires only 130 KB RAM, 350 KB ROM. Although, if you come to a Java User Group meeting in Moscow on January 30 http://jug.msk.ru, you will be surprised how small the platform can be if you work on it with a file. Alexander Mironenko alexanderVmironenko will tell how he “crammed” Java into 32kb! RAM A full, standard configuration requires more memory: 700kb RAM and 2000kb ROM, which by modern standards still seems ridiculous.

Everyone wants everyone around to be smart. It’s nice to communicate with smart people, and it’s comfortable to live in a smart home. This is probably why most of the projects with Arduido and Raspberry Pi have a pronounced focus on pumping the skills of our home. A typical task is temperature monitoring.
For temperature monitoring, we first used sensors with an SPI interface. But later it turned out that sensors with I2C are much cheaper. To make a thermometer from Raspberry Pi and Oracle Java ME Embedded 3.3, we need a Dalas Semiconductor DS1621 digital temperature sensor in a DIP8 package. Here you can buy it for 173 rubles http://www.electronshik.ru/item/ds1621-232961 .
We connect it to the GPIO terminals of our board
DS1621 | Raspberry gpio pins |
pin1 | SDA (GPIO 2) |
pin2 | SCL (GPIO 3) |
pin4 | GND |
pin8 | 3.3v |
If you read the Datasheet on DS1621, you can find out that the sensor address on the bus is configured using pins 5-6-7 in our example, we will set them all to 1 by shorting it to power.

We believe that you already have Raspbian and it has been updated.
In order for us to be able to work with the I2C interface on the Raspberry Pi. You must download the appropriate module.
Add two lines to / etc / modules
i2c-bcm2708
i2c-dev
We overload the board.
Installing utilities for working with I2C
sudo apt-get install i2c-tools
We determine the address of our device on the I2C bus
sudo i2cdetect -y 1
The address of our 4f sensor (remember this number)
Download the stable version of Oracle Java ME Embedded 3.3 for Raspberry Pi Model B. In version 3.4, only support for the Qualcomm IoE platform was added. We preliminary accept the license agreement. http://www.oracle.com/technetwork/java/embedded/downloads/javame/index.html?ssSourceSiteId=ocomen
Copy runtime to Raspberry and deploy it to a convenient place.
For example, in ~ / JavaME /
And from root, run AMS (Application Management System)
sudo ~/JavaME/bin/usertest.sh
C Raspberry Pi finished.
Install the Java ME SDK and plugin for NetBeans or Eclipse on your computer. http://www.oracle.com/technetwork/java/javame/javamobile/download/sdk/default-303768.html
Add our Malinka as a device for deploying the midlet.
In the NetBeans menu, select Tools / Java ME / Device selector
In the Device selector window, press Ctrl-D and create a new device. To do this, simply register the address of our board, click Next and if everything is in order, select the level of logging.
Creating a Java ME / Embedded Application Project
The IDE will create for us the skeleton of a Java ME application that inherits from the MIDlet class and consists of three methods: startApp (), pauseApp (), and destroyApp (boolean unconditional). The startApp () method will start when the MIDlet starts, in it, for simplicity, we will write the code for our application.
Java ME Embedded provides us with a high-level peripheral communication API - DAAPI (Deveice Access API). To work with I2C, we need to create a device configuration, transfer it to the PeripheralManager.open () factory and if all the wires are OK and Java is running as root, we will get an instance of the I2CDevice () class that will allow us to communicate with the sensor.
Below is a sample Java ME application code, if something is not clear, ask questions in the comments, come to the Oracle office in St. Petersburg or on January 30 athttp://jug.msk.ru
To run this code on the device, right-click on your project in NetBeans, select Run with ... and select your Raspberry in the Quick Project Run window that opens. Or in the project properties, select the Platform tab, select your device as Device, then NetBeans will deploy the application to Rapberry Pi by default when the project starts.
Now you know the temperature in the room :)
Useful links:
Java ME Embedded 3.3 for Raspberry Pi
Java ME SDK 3.4
Java ME Embedded 3.3 Getting Started Guide for the Reference Platform (Raspberry Pi)
DS1621 Datasheet Thermal Sensor
import com.oracle.deviceaccess.PeripheralManager;
import com.oracle.deviceaccess.i2cbus.I2CDevice;
import com.oracle.deviceaccess.i2cbus.I2CDeviceConfig;
import java.io.IOException;
import javax.microedition.midlet.*;
public class IMlet extends MIDlet {
private final int CFG_ADDRESS = 0x4f; //Адрес датчика
private final int FREQ = 100000; //Частота шины из Datasheet
private final int ADDRESS_SIZE = 7; //Размер адреса из Datasheet
private final int BUS_ID = 1; // Внутренний идентификатор шины в Java ME Embedded из Getting Started Guide
// Адреса регистров и значения конфигурационных параметров датчика DS1621 подробнее в Datasheet
private final int REG_READ_TEMP = 0xAA;
private final int RT_ADDR_SIZE = 0x01;
private final int READ_TEMP_SIZE = 0x02;
private final int READ_TEMP_VAL = 0x00;
private final int REG_ACC_CONF = 0xAC;
private final int ACC_CONF_VAL = 0x00;
private final int REG_START_CONV = 0xEE;
private final int REG_STOP_CONV = 0x22;
public void startApp() {
// Создаем конфиг
I2CDeviceConfig config = new I2CDeviceConfig(BUS_ID, CFG_ADDRESS, ADDRESS_SIZE, FREQ);
I2CDevice device = null;
try {
// Открываем устройство
device = (I2CDevice) PeripheralManager.open(config);
// Конфигурируем датчика на непрерывное измерение температуры
write(device, new byte[]{(byte) REG_ACC_CONF, (byte) ACC_CONF_VAL});
write(device, new byte[]{(byte) REG_START_CONV});
// Читаем температуру
byte temp[] = new byte[READ_TEMP_SIZE];
device.read(REG_READ_TEMP, RT_ADDR_SIZE, temp, 0, READ_TEMP_SIZE);
// Profit!
System.out.println("Temperature is:" + temp[0]);
} catch (Exception ex) { // Никогда так не делайте, только для Habrahabr
ex.printStackTrace();
} finally {
// Закрываем устройство
if(device != null) {
try {
device.close();
} catch (IOException ex) {
ex.printStackTrace();
}
// Скажем приложению, что ему нужно самоуничтожится
notifyDestroyed();
}
}
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
private void write(I2CDevice i2c, byte[] buffer) {
try {
i2c.begin();
i2c.write(buffer, 0, buffer.length);
i2c.end();
} catch (IOException ex) {
System.out.println("[I2CThermometerTest] configure exception: " + ex.getMessage());
} catch (Exception ex) {
System.out.println("[I2CThermometerTest] Peripherial not available exception: " + ex.getMessage());
}
}
}