Measuring temperature with Raspberry Pi, I2C sensor and Java ME 8

Nowadays, developers reveal their growing interest to the microcontrollers, devices based on ARM processors, and other non-traditional hardware. To satisfy the increasing demand, the market introduced  Arduino, Beagle Board, Raspberry Pi, and many other devices.
Oracle provides two Java platforms for ARM-based devices. Whereas Java SE Embedded is aimed for powerful hardware,  Java ME Embedded works better for resource-constrained devices.


Oracle Java ME Embedded is a Java Runtime optimized for constrained ARM based devices. Minimally acceptable requirements for Java ME embedded are 128Kb of RAM and 1Mb of ROM. Using Java ME Embedded in your projects can bring several benefits. First of all,  "write once, run everywhere" principle, now with some restrictions can be applied to embedded world. Second, AMS (Application Management System), integrated into the platform. enables deploying, updating, starting, stopping, and destroying applications. Third, you have an API to access peripheral, such as SPI, I2C, URAT, and GPIO pins (DAAPI - Device Access API). Forth,, you will get a free and powerful developer tools as well as a set of standard services: File I/O (JSR 75), Wireless Messaging (JSR 120), Web Services (JSR 172), Security and Trust Services Subset (SATSA – JSR 177), Location (JSR 179), and XML (JSR 280).


As you can see, Oracle Java ME Embedded is a cross-platform product, which supports a set of ARM based devices. The current version is Oracle Java ME 8. The platform is ported to ARM11/Linux (Raspberry Pi Model B), ARM9/BREW MP (Qualcomm IoE development), and X86/Windows (emulator). These are reference implementations developed by Oracle engineers. If there is customer’s need, the platform can be ported to other devices.

Smart home


Personally, I would really like to see my home automated. It is always a true pleasure to communicate with smart people and a real delight to live in a smart home. The first idea that usually strikes my mind when I’ve got a small piece of hardware is to automate something at my house. A typical task is a temperature monitoring.
To monitor temperature you can use UART, SPI, or I2C sensors. Usually, I2C ones are a bit cheaper, so that I will use Dallas Semiconductor DS1621 in DIP8 form factor to make a digital thermometer with Raspberry Pi and Java ME Embedded.

Raspberry Pi hardware setup

First of all, we need to physically connect the sensor and a RPi
pin1 - SDL
pin2 - SCL
pin4 - GND
pin8 - Vdd


If you read a datasheet of DS1621, you know that the sensor address at the I2C bus can be configured by pins 5-6-7. For our sensor, let's turn them all to 1 by closing contacts to the power.



Setup software at Raspberry Pi

Install Raspbian and update it.
To enable I2C interface on Raspberry Pi it is necessary to upload the relevant module
add 2 lines to /etc/modules

i2c-bcm2708
i2c-dev


Reboot RPi
Install Linux tools to operate with I2C
sudo apt-get install i2c-tools

Detect an address of our sensor

sudo  i2cdetect -y 1

address is 4f (remember it)


Download Oracle Java ME Embedded 8  for Raspberry Pi Model B.
Accept a license agreements http://www.oracle.com/technetwork/java/embedded/javame/embed-me/downloads/index.html
Copy Runtime to Raspberry Pi to your favorite location and unpack it
for instance ~/JavaME/

Start Runtime with AMS (Application Management System) under the root privileges
sudo ~/JavaME/bin/usertest.sh
We have just  finished with the RPi setup

Developer tools setup

If you have not yet played with Oracle Java ME SDK 8, set it up for Netbeans.
http://www.oracle.com/technetwork/java/embedded/javame/javame-sdk/downloads/index.html

Add our RPi as a deploying device
In NetBeans choose: Tools -> Java ME -> Device selector
The most probably your Raspberry already autodetected by Java ME SDK and exists in the list of connected devices. If it is not, you can find the Device Connection Manager in your Windows tray and add RPi manually.  To do it, just click add and write the IP address of your RPi and define a debug level you need.

Create a new project in Netbeans:  New Project -> Java ME -> Embedded application

IDE creates a skeleton of Java ME application, which extends a MIDlet class  and consists of 3 methods: startApp(), pauseApp(), anddestroyApp(boolean unconditional)

Java ME Embedded provides us with an API to communicate with peripherals – DIO API (Device Input/Output API). To operate with I2C, we need to create a configuration of the device, pass it to the factory DeviceManager.open(), and if everything is alright, we will get an instance of the I2CDevice class required to communicate with the sensor.

To allow your application to use a specific API on the device you need to set up API Permissions.

In Netbeans click right button on your project in Project Properties go to tab Application Descriptor and to access I2C device add 2 lines:

Permission Protected Resource Name
Action Requested

jdk.dio.DeviceMgmtPermission

*:*

open

jdk.dio.i2cbus.I2CPinPermission

*:*

open



To run a code below on your RPi, right-click  on your device in Device Selector window, and under "Run project" menu click on the project you would like to run on Raspberry. Alternatively,  you can use the project properties in Platform tab to define a Device. In that’s the case, NetBeans always uses RPi as a target device for deployment.

Now you should know the temperature in room.

The best collection of docs about Java ME Embedded 8 can be found here: http://docs.oracle.com/javame/8.0/
Have fun!

/*
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

import javax.microedition.midlet.MIDlet;

import java.io.IOException;
import java.nio.ByteBuffer;
import jdk.dio.DeviceManager;
import jdk.dio.i2cbus.I2CDevice;
import jdk.dio.i2cbus.I2CDeviceConfig;

public class JavaMEThermometer extends MIDlet {

    private final int CFG_ADDRESS = 0x4f;  //Sensor address
    private final int FREQ = 100000;  //Bus frequency from Datasheet
    private final int ADDRESS_SIZE = 7; //Address size from Datasheet
    private final int BUS_ID = 1; // Internal bus ID in Java ME Embedded from Getting Started Guide

    // Registers addresses and definitions of configuration parameters of DS1621 from 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() {
        // Create a configuration
        I2CDeviceConfig config = new I2CDeviceConfig(BUS_ID, CFG_ADDRESS, ADDRESS_SIZE, FREQ);
        I2CDevice device = null;
        try  {

            // Open device using configuration
            device = (I2CDevice) DeviceManager.open(config);

            // Config sensor to continuous temperature measuring according to Datasheet
            write(device, new byte[]{(byte) REG_ACC_CONF, (byte) ACC_CONF_VAL});
            write(device, new byte[]{(byte) REG_START_CONV});

            // Read temperature
            ByteBuffer tempBuf = ByteBuffer.allocateDirect(READ_TEMP_SIZE);
            device.read(REG_READ_TEMP, RT_ADDR_SIZE,tempBuf);
             // Profit!  
            System.out.println("Temperature is:" + tempBuf.get(0));

        } catch (Exception ex) { // Bad practice. Only for consiceness
            ex.printStackTrace();
        } finally {
            // Close device
            if (device != null) {
                try {
                    device.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                // Destroy application
                notifyDestroyed();
            }

        }
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    private void write(I2CDevice i2c, byte[] buffer) {
        try {
            i2c.begin();
            i2c.write(ByteBuffer.wrap(buffer));
            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());
        }
    }
}
Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

Topics including Java ME embedded, Java ME SDK, Internet of Things, Edge devices, Java on MCU and more

Search

Archives
« July 2015
SunMonTueWedThuFriSat
   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 
       
Today