Friday May 10, 2013

Error:Could not find Java SE Environment (ME 3.3 SDK)

So after upgrading all the JVMs on my laptop I ran into an issue when trying to use the Java ME Embedded 3.3 SDK. I got the following error message:

The solution was easy (after a little digging around in the installation directory of the ME SDK. Open the file called java, it is located in the bin directory and change the path to correct one and bam it works again.

<<Andy>> 

Friday Apr 12, 2013

Using Java ME 3.3 on Raspberry Pi to read the temp in my office Part #2

So here is the source code to read the sensor connected according to the description in the previous blog post. Now, this sample is just developed without considerations for footprint, power consumption etc which is so important when developing an embedded application in any language (but Java should obviously be the the choice).

First the IMlet, nothing really strange here at all

 package tmp36rpi;  
 import javax.microedition.midlet.*;  
 /**  
  * @author atael  
  */  
 public class IMlet extends MIDlet {  
   private MCP3008Checker mcp3008Checker;  
   private static final String name = "MCP3008";  
   public void startApp() {  
     System.out.println("***************************************");  
     System.out.println("* MCP3008/TMP36 Thermometer Sample  *");  
     System.out.println("***************************************");  
     mcp3008Checker = new MCP3008Checker(name);  
     if (mcp3008Checker.start() ) {  
       System.out.println("MCP3008Checker start is OK.");  
     } else {  
       System.out.println("MCP3008Checker start has failed.");  
     }  
   }  
   public void pauseApp() {  
   }  
   public void destroyApp(boolean unconditional) {  
     if (mcp3008Checker != null) {  
       mcp3008Checker.stop();  
     }  
   }  
 }  
Then my helper class, MCP3008Checker, which extends TimerTask and I have hard coded that it should execute every 5000ms. When it kicks in it will get the temperature from the TMP36 class (see below):
 /*  
  * To change this template, choose Tools | Templates  
  * and open the template in the editor.  
  */  
 package tmp36rpi;  
   
 import java.util.Timer;  
 import java.util.TimerTask;  
   
 /**  
  *  
  * @author atael  
  */  
 public class MCP3008Checker extends TimerTask {  
   
   private Timer timer;  
   private static int INTERVAL_MS = 5000;  
   private int temperature;  
   private String name;  
     
     
   MCP3008Checker( String name){    
     this.name = name;  
   }  
     
   public boolean start () {  
     boolean isStarted = false;  
     System.out.println ("Trying...");  
     if (TMP36.connect()) {  
       timer = new Timer();  
       timer.schedule(this, 0, INTERVAL_MS);  
       temperature = TMP36.getTemperature();  
       isStarted = true;  
     }  
     return isStarted;  
   }  
     
   public void run() {  
     int newTemperature = TMP36.getTemperature();  
     if (newTemperature != temperature) {  
       temperature = newTemperature;  
     }  
     System.out.println("Temp in Andys office: " + temperature );  
   }  
     
   public void stop () {  
     if (timer != null) {  
       timer.cancel ();  
     }  
     TMP36.disconnect();  
   }  
 }  
   

The TMP36 class is the part of the code that "talks" to the MCP3008. This is the hard part according to me becuase I am pretty junior on how to read hardware documentation and understanding bits and bytes. But I'll learn as I go (with great help from other colleagues):

 package tmp36rpi;  
   
 import com.oracle.deviceaccess.Peripheral;  
 import com.oracle.deviceaccess.PeripheralConfigInvalidException;  
 import com.oracle.deviceaccess.PeripheralExistsException;  
 import com.oracle.deviceaccess.PeripheralManager;  
 import com.oracle.deviceaccess.PeripheralNotAvailableException;  
 import com.oracle.deviceaccess.PeripheralNotFoundException;  
 import com.oracle.deviceaccess.PeripheralTypeNotSupportedException;  
 import com.oracle.deviceaccess.gpio.GPIOPin;  
 import com.oracle.deviceaccess.spibus.SPIDevice;  
 import com.oracle.deviceaccess.spibus.SPIDeviceConfig;  
 import java.io.IOException;  
   
 /**  
  *  
  * @author atael  
  */  
 public class TMP36 {  
   
   private static SPIDevice mcp3008 = null;  
   private static GPIOPin cs = null;  
   private static final int spiBusNumber = 0; // number of the bus the slave device is connected to  
   private static final int spiAddress = 1; // Chip Select address of the slave device on the bus  
   private static final int spiClockFrequency = 7500; // clock frequency of the slave device in Hz  
   private static final int spiClockMode = 2;   
   private static final int spiWordLength = 8;  
   private static final int spiBitOrdering = Peripheral.BIG_ENDIAN;  
   
   public static boolean connect() {  
     boolean isConnected = false;  
     try {  
       cs = (GPIOPin) PeripheralManager.open(18);  
         
       SPIDeviceConfig spiCfg = new SPIDeviceConfig(  
           spiBusNumber,   
           spiAddress,   
           spiClockFrequency,   
           spiClockMode,   
           spiWordLength,   
           spiBitOrdering);  
         
       cs.setValue(true);  
       mcp3008 = (SPIDevice) PeripheralManager.open(SPIDevice.class, spiCfg);  
       isConnected = true;  
         
     } catch (PeripheralNotAvailableException ex) {  
       ex.printStackTrace();  
     } catch (PeripheralNotFoundException ex) {  
       ex.printStackTrace();  
     } catch (PeripheralTypeNotSupportedException ex) {  
       ex.printStackTrace();  
     } catch (IOException ex) {  
       ex.printStackTrace();  
     } catch (PeripheralConfigInvalidException ex) {  
       ex.printStackTrace();  
     } catch (PeripheralExistsException ex) {  
       ex.printStackTrace();  
     }  
     return isConnected;  
   }  
   
   public static void disconnect() {  
     if (mcp3008 != null) {  
       try {  
         if (cs.isOpen()) {  
           cs.close();  
         }  
         if (mcp3008.isOpen()) {  
           mcp3008.close();  
         }  
       } catch (IOException ex) {  
         ex.printStackTrace();  
       }  
     }  
   }  
   
   public static int getTemperature() {  
       
     int readAdc = 0;  
     float milliVolts = 0;  
     float tempCelsius = 0;  
       
     try {  
       cs.setValue(false);  
       
       byte[] rxBuf = new byte[3];  
       byte[] txBuf = new byte[3];  
       txBuf[0] = (byte) 1;  
       txBuf[1] = (byte) ((8 + 0) << 4);  
       txBuf[2] = (byte) 0;  
             
       mcp3008.begin();  
       mcp3008.writeAndRead(txBuf, 0, txBuf.length, rxBuf, 0, rxBuf.length);  
       mcp3008.end();  
         
       cs.setValue(true);  
   
       readAdc = convUnsignedByte(rxBuf[2]);
       readAdc += ((rxBuf[1] & 3) << 8);  
          
       /* TMP36 Formula: Temp °C = 100*(reading in V) - 50  
        *   
        * The MCP3008 is a 10-bit ADC. That means it will read a value   
        * from 0 to 1023 (2^^10 = 1024 values) where 0 is the same as   
        * 'ground' and '1023' is the same as '3.3 volts'.   
       */  
          
       // Convert analog reading to millivolts  
       milliVolts = readAdc * (3300 / 1023);  
         
       // 10 mv per degree  
       tempCelsius = ((milliVolts - 100) / 10) - 40;  
                
       return (int)tempCelsius;  
         
     } catch (PeripheralNotAvailableException ex) {  
       ex.printStackTrace();  
     } catch (IOException ex) {  
       ex.printStackTrace();  
     }  
     return 0;  
   }  
     
   public static int convUnsignedByte (byte value) {  
     int returnValue = value;  
     if (value < 0) {  
       returnValue = 0xFF + value + 1;        
     }    
     return returnValue;  
   }   
 }  

And when I execute this I can see the following in my console. It is a lot of information that gets written but I do have a temperature of 18 degress celsius and if I put my finger on my sensor I can see the temperature go up. So it seems that it works!

 ***************************************  
 * MCP3008/TMP36 Thermometer Sample  *  
 ***************************************  
 Trying...  
 [INFO] [UNKNOWN] gpio.c line 636: Try to open pin 18 on port 0 with direction 1  
 [INFO] [UNKNOWN] gpio.c line 727: GPIO pin 18 open successfully done  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 1  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 0  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 1  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 MCP3008Checker start is OK.  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 0  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 [AMS-TRACE] MIDlet:TMP36rpi status=1  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 1  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 Temp in Andys office: 18  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 0  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 1  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 Temp in Andys office: 18  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 0  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 1  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 Temp in Andys office: 18  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 0  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 1  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 Temp in Andys office: 19  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 0  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 1  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 Temp in Andys office: 19  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 0  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 [INFO] [UNKNOWN] gpio.c line 551: Pin 18 direction: 1  
 [INFO] [UNKNOWN] gpio.c line 305: Pin 18 write value 1  
 [INFO] [UNKNOWN] gpio.c line 312: Pin 18 write value done  
 Temp in Andys office: 20  

That's all for now folks. Now I am going to figure out how to make this application to auto start and how to make this very important information available to a end-user application such a servlet, JavaFX application or something like that. That means lot's of reading and I will blog about the findings. I will also connect other types of sensors, just because I think it is fun to build embedded applications with Java (and I need to impress my dog as he is the only one in my family that thinks this is cool).

<<Andy>> 

Using Java ME 3.3 on Raspberry Pi to read the temp in my office Part #1

This will be a pretty long entry, but I'd like to get this blog post out. I think it is really cool and I am hoping that other people think so too. 

On my previous blog I have documented how I was trying to read the temperature in my office using a TMP36 sensor and a MCP3008 A/D converter with no success. But after posting my problem to the Java Embedded OTN Forum I got some really good help from a colleague and now I think I got it working properly (what's missing is that I need to bring in a regular thermometer to verify my results).

The first thing I learned was that there is a problem with the current SPI implementation on the Raspberry Pi, so I needed to move the MCP3008 CS to GPIO18 (instead of GPIO8 which is the CE in the documentation) and then control the CS manually. 

Secondly I needed to decrease the clock frequency and change the mode of the SPI interface. I am not 100% sure why I need to do this (read: I am no HW expert but I am trying to read up why I needed to do this).

So now is the system wired up like this:

  • MCP3008 VDD --> 3.3V
  • MCP3008 VREF --> 3.3V
  • MCP3008 AGND --> GND
  • MCP3008 CLK --> SCLK (GPIO11)
  • MCP3008 DOUT --> MISO (GPIO9)
  • MCP3008 DIN --> MOSI (GPIO10)
  • MCP3008 CS --> CE0 (GPIO18)
  • MCP3008 DGND --> GND

And there is no change to the TMP36 sensor:

The TMP36 sensor is very easy to wire up, with the flat side upwards:

  • Pin 1: 2.7-5.5V In -> 3.3V
  • Pin 2: Analog Voltage Out  -> CH0 on MCP3008
  • Pin 3: Ground -> GND

That's all for now folks, next post will give you the source code for this little but extremely cool project.

 <<Andy>> 

About

Andy's blog about the world of embedded Java

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
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
   
       
Today