Sunday, December 15, 2013

Reading Multiple 1-Wire Temperature Sensors Using Java on a Raspberry Pi

This example shows how a Java program can read temperature data from multiple DS18B20 1-wire temperature sensors.  This program prints the device number and temperature from each device in a continuous loop.  It works with Java 7 or Java 8.

Before running the program below, be sure to run the following commands to load the needed kernel modules -

sudo modprobe w1-gpio
sudo modprobe w1-therm


Connections


Looking at the flat side of the DS18B20's plastic head, connect the left pin to ground, the right pin to 3V3, and the center pin to GPIO4.  A 4.7k Ohm pull-up resistor is required on the connection of the first sensor's center pin to GPIO4.  If using multiple sensors, each needs to be connected to the voltage and ground; parasitic power mode does not seem to be supported.  The center (data) pins need to be connected together (with the pull-up on the connection to the Raspberry Pi).


Java Code



import java.io.*;
import java.util.*;

public class w1 {
  //This directory created by 1-wire kernel modules
  static String w1DirPath = "/sys/bus/w1/devices";

  public static void main(String[] argv) throws Exception {
    File dir = new File(w1DirPath);
    File[] files = dir.listFiles(new DirectoryFileFilter());
    if (files != null) {
      while(true) {
        for(File file: files) {
          System.out.print(file.getName() + ": ");
  // Device data in w1_slave file
          String filePath = w1DirPath + "/" + file.getName() + "/w1_slave";
          File f = new File(filePath);
          try(BufferedReader 
              br = new BufferedReader(new FileReader(f))) {
            String output;
            while((output = br.readLine()) != null) {
              int idx = output.indexOf("t=");
              if(idx > -1) {
                // Temp data (multiplied by 1000) in 5 chars after t=
                float tempC = Float.parseFloat(
                    output.substring(output.indexOf("t=") + 2));
                // Divide by 1000 to get degrees Celsius
tempC /= 1000;
System.out.print(String.format("%.3f ", tempC));
float tempF = tempC * 9 / 5 + 32;
System.out.println(String.format("%.3f", tempF));
              }
            }
          }
          catch(Exception ex) {
            System.out.println(ex.getMessage());
          }
        }
      }
   } 
}

// This FileFilter selects subdirs with name beginning with 28-
// Kernel module gives each 1-wire temp sensor name starting with 28-
class DirectoryFileFilter implements FileFilter
{
   public boolean accept(File file) {
     String dirName = file.getName();
     String startOfName = dirName.substring(0, 3);
     return (file.isDirectory() && startOfName.equals("28-"));
   }
}  


6 comments:

  1. Wow, really cool that you have posted this Brad, I would have no idea where to start capturing the temp from Java...so thanks a lot! BIG help! :)

    Can I please ask though as I have had a nightmare problem the past few hours ...how do I redirect System.out.print(String.format("%.3f ", tempC)). to a JFrame/JPanel?

    Please can you help me or shed so light could I can view the output from the temp sensors in a JFrame please,
    All I get is a blank JPanel

    Cheers in advance!
    Bubz

    ReplyDelete
  2. Since I'm not a java guy, where does this code go and what name should it have?
    Do I need to do something special for this to work?

    ReplyDelete
  3. Please tell the procedure to load and run it on the pi kit...
    please help...Thank u..

    ReplyDelete
  4. should i use java SE or java ME...
    If java SE then which version to use...
    Pls help

    ReplyDelete
  5. Being a complete Java newbie, i spent hours figuring this out. Here is what I did:
    1. Use nano to create a new file called w1.java. You need to name it that!
    2. Copy and paste the code above into this file.
    3. Add another curly bracket } after this line: System.out.println(ex.getMessage());
    4. Save and exit nano. Remember file name must be w1.java!
    5. Compile the java program: $ javac w1.java This will create a file called w1.class in your current directory.
    6. Run the program: $ java w1

    Remember also:
    1. $ sudo modprobe w1-gpio
    2. $ sudo modprobe w1-therm (these two lines load those modules. You will need to do again after a reboot.)
    3. Connect DS18B20 (yellow to gpio4, red to 3v. or 5v., black to gnd.) 4.7K ohm resistor across red-yellow. (I am actually using 2K ohm)

    ReplyDelete