read temperature from DHT11, using pi4j
up vote
4
down vote
favorite
I'm trying to read temperature data from a DHT11 temperature sensor, using pi4j. I followed the code written in c and python in this site:
http://www.uugear.com/portfolio/dht11-h ... or-module/
But it's not working. when I test the instruction 'dht11Pin.getState()' it's always in HIGH state, never changing. Is there anything wrong in my code?
Below is my code:
import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.pi4j.component.ObserveableComponentBase;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalMultipurpose;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.PinMode;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
public class DHT11 extends ObserveableComponentBase {
private static final Pin DEFAULT_PIN = RaspiPin.GPIO_04;
private static final int MAXTIMINGS = 85;
private int dht11_dat = { 0, 0, 0, 0, 0 };
private GpioPinDigitalMultipurpose dht11Pin;
private static final Logger LOGGER = LogManager.getLogger(DHT11.class
.getName());
public DHT11() {
final GpioController gpio = GpioFactory.getInstance();
dht11Pin = gpio.provisionDigitalMultipurposePin(DEFAULT_PIN,
PinMode.DIGITAL_INPUT, PinPullResistance.PULL_UP);
}
public DHT11(int pin) {
final GpioController gpio = GpioFactory.getInstance();
dht11Pin = gpio.provisionDigitalMultipurposePin(LibPins.getPin(pin),
PinMode.DIGITAL_INPUT, PinPullResistance.PULL_UP);
}
public double getTemperature() {
PinState laststate = PinState.HIGH;
int j = 0;
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
StringBuilder value = new StringBuilder();
try {
dht11Pin.setMode(PinMode.DIGITAL_OUTPUT);
dht11Pin.low();
Thread.sleep(18);
dht11Pin.high();
TimeUnit.MICROSECONDS.sleep(40);
dht11Pin.setMode(PinMode.DIGITAL_INPUT);
for (int i = 0; i < MAXTIMINGS; i++) {
int counter = 0;
while (dht11Pin.getState() == laststate) {
counter++;
TimeUnit.MICROSECONDS.sleep(1);
if (counter == 255) {
break;
}
}
laststate = dht11Pin.getState();
if (counter == 255) {
break;
}
/* ignore first 3 transitions */
if ((i >= 4) && (i % 2 == 0)) {
/* shove each bit into the storage bytes */
dht11_dat[j / 8] <<= 1;
if (counter > 16) {
dht11_dat[j / 8] |= 1;
}
j++;
}
}
// check we read 40 bits (8bit x 5 ) + verify checksum in the last
// byte
if ((j >= 40) && checkParity()) {
value.append(dht11_dat[2]).append(".").append(dht11_dat[3]);
LOGGER.info("temperature value readed: " + value.toString());
}
} catch (InterruptedException e) {
LOGGER.error("InterruptedException: " + e.getMessage(), e);
}
if (value.toString().isEmpty()) {
value.append(-1);
}
return Double.parseDouble(value.toString());
}
private boolean checkParity() {
return (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF));
}
}
java raspberry-pi sensor pi4j
add a comment |
up vote
4
down vote
favorite
I'm trying to read temperature data from a DHT11 temperature sensor, using pi4j. I followed the code written in c and python in this site:
http://www.uugear.com/portfolio/dht11-h ... or-module/
But it's not working. when I test the instruction 'dht11Pin.getState()' it's always in HIGH state, never changing. Is there anything wrong in my code?
Below is my code:
import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.pi4j.component.ObserveableComponentBase;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalMultipurpose;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.PinMode;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
public class DHT11 extends ObserveableComponentBase {
private static final Pin DEFAULT_PIN = RaspiPin.GPIO_04;
private static final int MAXTIMINGS = 85;
private int dht11_dat = { 0, 0, 0, 0, 0 };
private GpioPinDigitalMultipurpose dht11Pin;
private static final Logger LOGGER = LogManager.getLogger(DHT11.class
.getName());
public DHT11() {
final GpioController gpio = GpioFactory.getInstance();
dht11Pin = gpio.provisionDigitalMultipurposePin(DEFAULT_PIN,
PinMode.DIGITAL_INPUT, PinPullResistance.PULL_UP);
}
public DHT11(int pin) {
final GpioController gpio = GpioFactory.getInstance();
dht11Pin = gpio.provisionDigitalMultipurposePin(LibPins.getPin(pin),
PinMode.DIGITAL_INPUT, PinPullResistance.PULL_UP);
}
public double getTemperature() {
PinState laststate = PinState.HIGH;
int j = 0;
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
StringBuilder value = new StringBuilder();
try {
dht11Pin.setMode(PinMode.DIGITAL_OUTPUT);
dht11Pin.low();
Thread.sleep(18);
dht11Pin.high();
TimeUnit.MICROSECONDS.sleep(40);
dht11Pin.setMode(PinMode.DIGITAL_INPUT);
for (int i = 0; i < MAXTIMINGS; i++) {
int counter = 0;
while (dht11Pin.getState() == laststate) {
counter++;
TimeUnit.MICROSECONDS.sleep(1);
if (counter == 255) {
break;
}
}
laststate = dht11Pin.getState();
if (counter == 255) {
break;
}
/* ignore first 3 transitions */
if ((i >= 4) && (i % 2 == 0)) {
/* shove each bit into the storage bytes */
dht11_dat[j / 8] <<= 1;
if (counter > 16) {
dht11_dat[j / 8] |= 1;
}
j++;
}
}
// check we read 40 bits (8bit x 5 ) + verify checksum in the last
// byte
if ((j >= 40) && checkParity()) {
value.append(dht11_dat[2]).append(".").append(dht11_dat[3]);
LOGGER.info("temperature value readed: " + value.toString());
}
} catch (InterruptedException e) {
LOGGER.error("InterruptedException: " + e.getMessage(), e);
}
if (value.toString().isEmpty()) {
value.append(-1);
}
return Double.parseDouble(value.toString());
}
private boolean checkParity() {
return (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF));
}
}
java raspberry-pi sensor pi4j
add a comment |
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I'm trying to read temperature data from a DHT11 temperature sensor, using pi4j. I followed the code written in c and python in this site:
http://www.uugear.com/portfolio/dht11-h ... or-module/
But it's not working. when I test the instruction 'dht11Pin.getState()' it's always in HIGH state, never changing. Is there anything wrong in my code?
Below is my code:
import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.pi4j.component.ObserveableComponentBase;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalMultipurpose;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.PinMode;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
public class DHT11 extends ObserveableComponentBase {
private static final Pin DEFAULT_PIN = RaspiPin.GPIO_04;
private static final int MAXTIMINGS = 85;
private int dht11_dat = { 0, 0, 0, 0, 0 };
private GpioPinDigitalMultipurpose dht11Pin;
private static final Logger LOGGER = LogManager.getLogger(DHT11.class
.getName());
public DHT11() {
final GpioController gpio = GpioFactory.getInstance();
dht11Pin = gpio.provisionDigitalMultipurposePin(DEFAULT_PIN,
PinMode.DIGITAL_INPUT, PinPullResistance.PULL_UP);
}
public DHT11(int pin) {
final GpioController gpio = GpioFactory.getInstance();
dht11Pin = gpio.provisionDigitalMultipurposePin(LibPins.getPin(pin),
PinMode.DIGITAL_INPUT, PinPullResistance.PULL_UP);
}
public double getTemperature() {
PinState laststate = PinState.HIGH;
int j = 0;
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
StringBuilder value = new StringBuilder();
try {
dht11Pin.setMode(PinMode.DIGITAL_OUTPUT);
dht11Pin.low();
Thread.sleep(18);
dht11Pin.high();
TimeUnit.MICROSECONDS.sleep(40);
dht11Pin.setMode(PinMode.DIGITAL_INPUT);
for (int i = 0; i < MAXTIMINGS; i++) {
int counter = 0;
while (dht11Pin.getState() == laststate) {
counter++;
TimeUnit.MICROSECONDS.sleep(1);
if (counter == 255) {
break;
}
}
laststate = dht11Pin.getState();
if (counter == 255) {
break;
}
/* ignore first 3 transitions */
if ((i >= 4) && (i % 2 == 0)) {
/* shove each bit into the storage bytes */
dht11_dat[j / 8] <<= 1;
if (counter > 16) {
dht11_dat[j / 8] |= 1;
}
j++;
}
}
// check we read 40 bits (8bit x 5 ) + verify checksum in the last
// byte
if ((j >= 40) && checkParity()) {
value.append(dht11_dat[2]).append(".").append(dht11_dat[3]);
LOGGER.info("temperature value readed: " + value.toString());
}
} catch (InterruptedException e) {
LOGGER.error("InterruptedException: " + e.getMessage(), e);
}
if (value.toString().isEmpty()) {
value.append(-1);
}
return Double.parseDouble(value.toString());
}
private boolean checkParity() {
return (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF));
}
}
java raspberry-pi sensor pi4j
I'm trying to read temperature data from a DHT11 temperature sensor, using pi4j. I followed the code written in c and python in this site:
http://www.uugear.com/portfolio/dht11-h ... or-module/
But it's not working. when I test the instruction 'dht11Pin.getState()' it's always in HIGH state, never changing. Is there anything wrong in my code?
Below is my code:
import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.pi4j.component.ObserveableComponentBase;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalMultipurpose;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.PinMode;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
public class DHT11 extends ObserveableComponentBase {
private static final Pin DEFAULT_PIN = RaspiPin.GPIO_04;
private static final int MAXTIMINGS = 85;
private int dht11_dat = { 0, 0, 0, 0, 0 };
private GpioPinDigitalMultipurpose dht11Pin;
private static final Logger LOGGER = LogManager.getLogger(DHT11.class
.getName());
public DHT11() {
final GpioController gpio = GpioFactory.getInstance();
dht11Pin = gpio.provisionDigitalMultipurposePin(DEFAULT_PIN,
PinMode.DIGITAL_INPUT, PinPullResistance.PULL_UP);
}
public DHT11(int pin) {
final GpioController gpio = GpioFactory.getInstance();
dht11Pin = gpio.provisionDigitalMultipurposePin(LibPins.getPin(pin),
PinMode.DIGITAL_INPUT, PinPullResistance.PULL_UP);
}
public double getTemperature() {
PinState laststate = PinState.HIGH;
int j = 0;
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
StringBuilder value = new StringBuilder();
try {
dht11Pin.setMode(PinMode.DIGITAL_OUTPUT);
dht11Pin.low();
Thread.sleep(18);
dht11Pin.high();
TimeUnit.MICROSECONDS.sleep(40);
dht11Pin.setMode(PinMode.DIGITAL_INPUT);
for (int i = 0; i < MAXTIMINGS; i++) {
int counter = 0;
while (dht11Pin.getState() == laststate) {
counter++;
TimeUnit.MICROSECONDS.sleep(1);
if (counter == 255) {
break;
}
}
laststate = dht11Pin.getState();
if (counter == 255) {
break;
}
/* ignore first 3 transitions */
if ((i >= 4) && (i % 2 == 0)) {
/* shove each bit into the storage bytes */
dht11_dat[j / 8] <<= 1;
if (counter > 16) {
dht11_dat[j / 8] |= 1;
}
j++;
}
}
// check we read 40 bits (8bit x 5 ) + verify checksum in the last
// byte
if ((j >= 40) && checkParity()) {
value.append(dht11_dat[2]).append(".").append(dht11_dat[3]);
LOGGER.info("temperature value readed: " + value.toString());
}
} catch (InterruptedException e) {
LOGGER.error("InterruptedException: " + e.getMessage(), e);
}
if (value.toString().isEmpty()) {
value.append(-1);
}
return Double.parseDouble(value.toString());
}
private boolean checkParity() {
return (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF));
}
}
java raspberry-pi sensor pi4j
java raspberry-pi sensor pi4j
edited Jan 17 '17 at 12:53
yglodt
6,42064581
6,42064581
asked Feb 12 '15 at 19:30
Júnior Mascarenhas
30115
30115
add a comment |
add a comment |
6 Answers
6
active
oldest
votes
up vote
7
down vote
accepted
I started with the original poster's java code, and replaced the com.pi4j.io.gpio package references with the com.pi4j.wiringpi package. I had recently installed the newest pi4j package and wiringpi version on my Raspberry Pi.
Using that package the Java code below works approximately the same as the c version of this program. I am getting about 80% - 85% accurate responses with a DHT-11. Which is about the same as I was getting using wiringPi in c.
package gpio;
import com.pi4j.wiringpi.Gpio;
import com.pi4j.wiringpi.GpioUtil;
public class DHT11 {
private static final int MAXTIMINGS = 85;
private final int dht11_dat = { 0, 0, 0, 0, 0 };
public DHT11() {
// setup wiringPi
if (Gpio.wiringPiSetup() == -1) {
System.out.println(" ==>> GPIO SETUP FAILED");
return;
}
GpioUtil.export(3, GpioUtil.DIRECTION_OUT);
}
public void getTemperature(final int pin) {
int laststate = Gpio.HIGH;
int j = 0;
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
Gpio.pinMode(pin, Gpio.OUTPUT);
Gpio.digitalWrite(pin, Gpio.LOW);
Gpio.delay(18);
Gpio.digitalWrite(pin, Gpio.HIGH);
Gpio.pinMode(pin, Gpio.INPUT);
for (int i = 0; i < MAXTIMINGS; i++) {
int counter = 0;
while (Gpio.digitalRead(pin) == laststate) {
counter++;
Gpio.delayMicroseconds(1);
if (counter == 255) {
break;
}
}
laststate = Gpio.digitalRead(pin);
if (counter == 255) {
break;
}
/* ignore first 3 transitions */
if (i >= 4 && i % 2 == 0) {
/* shove each bit into the storage bytes */
dht11_dat[j / 8] <<= 1;
if (counter > 16) {
dht11_dat[j / 8] |= 1;
}
j++;
}
}
// check we read 40 bits (8bit x 5 ) + verify checksum in the last
// byte
if (j >= 40 && checkParity()) {
float h = (float) ((dht11_dat[0] << 8) + dht11_dat[1]) / 10;
if (h > 100) {
h = dht11_dat[0]; // for DHT11
}
float c = (float) (((dht11_dat[2] & 0x7F) << 8) + dht11_dat[3]) / 10;
if (c > 125) {
c = dht11_dat[2]; // for DHT11
}
if ((dht11_dat[2] & 0x80) != 0) {
c = -c;
}
final float f = c * 1.8f + 32;
System.out.println("Humidity = " + h + " Temperature = " + c + "(" + f + "f)");
} else {
System.out.println("Data not good, skip");
}
}
private boolean checkParity() {
return dht11_dat[4] == (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3] & 0xFF);
}
public static void main(final String ars) throws Exception {
final DHT11 dht = new DHT11();
for (int i = 0; i < 10; i++) {
Thread.sleep(2000);
dht.getTemperature(21);
}
System.out.println("Done!!");
}
}
I have tried this, but the output is: "Data not good, skip"
– Dániel Kis
Nov 18 '16 at 22:20
This works for me, thanks a lot. I need ~25 reads (without delay) to get a valid value, but executed in a Loop this is no problem.
– Simulant
Mar 18 '17 at 23:36
Just out of curiosity: On which hardware type of Pi did you run this code?
– yglodt
Mar 26 '17 at 20:18
And another question: Do you think your code would also work for a DHT22 or AM2302?
– yglodt
Mar 26 '17 at 20:41
I used a Pi 2. I am not familiar with the DHT22 or AM2302, I have only tried it with the DHT11.
– Eric Smith
Mar 28 '17 at 2:12
|
show 4 more comments
up vote
0
down vote
If you're always getting a High State it might be good to double check if the wiring is correct (or if any of the wires are broken, test it with a led).
I've used adafruit's tutorial in C and python and it worked on my DHT22.
add a comment |
up vote
0
down vote
I've the same issue and, unfortunately, I've read that Java cannot read data from DHT11/22 in this way for timing problems.
I've found in the Raspberry Forum a thread where you can find some solutions using SPI or pigpio.
Another full Java possible solution is there.
I've received my sensor yesterday and I have not already tried this solutions. When I'll try, I'll let you know.
[EDIT]
Hi, I've solved the problem calling a python script (which uses the Adafruit Driver) and reading it's output.
The python script is simply the example published in the Adafruit's library. I've only changed the output at line 48 in
print '{0:0.1f} {1:0.1f}'.format(temperature, humidity)
The Java method that updates the values with new values is:
public void update() {
String cmd = "sudo python DHTReader.py 11 4";
try {
String ret = "";
try {
String line;
Process p = Runtime.getRuntime().exec(cmd.split(" "));
p.waitFor();
BufferedReader input = new BufferedReader
(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output += (line + 'n');
}
input.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
ret.trim();
if (ret.length() == 0) // Library is not present
throw new RuntimeException(LIB_NOT_PRESENT_MESSAGE);
else{
// Error reading the the sensor, maybe is not connected.
if(ret.contains(ERROR_READING)){
String msg = String.format(ERROR_READING_MSG,toString());
throw new Exception(msg);
}
else{
// Read completed. Parse and update the values
String vals = ret.split(" ");
float t = Float.parseFloat(vals[0].trim());
float h = Float.parseFloat(vals[1].trim());
if( (t != lastTemp) || (h != lastHum) ){
lastUpdate = new Date();
lastTemp = t;
lastHum = h;
}
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
if( e instanceof RuntimeException)
System.exit(-1);
}
}
To make it work you have to install the Adafruit library as described in the linked page and change DHTReader.py with the path of the scipt.
I'm working to build a "library". If you need, when I've finished, I'll publish it on GitHub.
add a comment |
up vote
0
down vote
I got a solution with Java Native Interface JNI and WiringPi.
I am using java openjdk 7 in the raspberry pi. This is important to for support JNI capabilites of the JVM. I connected the DHT11 sensor to GPIO1 or pin 1.
From the package root at src/main/java you can install the library. I prepared a script in that you can run with the command:
sudo sh jniDHT11SensorReaderBuilder.sh
Then to test if it works try to run the DHT11SensorReader class with the command
sudo java org.mandfer.dht11.DHT11SensorReader
If it is all fine and you want more values every 1.5 seconds try to run the exercise 20 from the project root folder.
sh runPi.sh org.mandfer.sunfunpi4j.Ex20_DHT11_Native
If you have any issue, leave me a comment.
I hope it helps.
Marc Andreu,
I am not able to compile this lib, Multiple errors first wiringpi.h not found, then no jni file. Can you give me workable script to get .so file for android
– Manoj
Jun 15 '17 at 11:03
Hello Manoj, did you try with the script jniDHT11SensorReaderBuilder.sh ? Make sure you are actually running JAVA OpenJDK 1.7 and run it from folder "src/main/java/" in the raspberry pi. Also follow make sure that you installed Pi4j and the wiringpi libs for your version of raspberry pi
– marcandreuf
Jun 16 '17 at 15:32
add a comment |
up vote
0
down vote
Eric Smith's excellent code works fine for me with two small mods, First I edited this line:
if (counter > 16)
To:
if (counter > 30)
According to specs of dht11, the "1" bit is transmitted when the delay of the "Gpio.HIGH" is about 70us, and "0" bit is transmitted if the delay is 26-28us. It is clear that Java takes some time to execute, so it is safe to assume that if the delay is more than 30us the data must be "1". But this might be different value if the execution time of Java program is different in your machine (perhaps the processor of pi is faster/slower, there is more background programs etc). Therefore, the 30 is not necessarily the right value for every situation.
According to specs 1, it can be also noted that sender (raspberry pi, called MCU in the specs), should also send Gpio.HIGH for at least 18ms. After that, the MCU should send 20-40 us "Gpio.HIGH". I tested with System.nanoTime() how much time it takes for the Java to execute setting the Gpio.Pinmode to the "Input". It took something like 20us, so I added:
Gpio.delayMicroseconds(7);
...just to be sure that the Pin is HIGH for at least 20us so that the Sensor can register that signal and start sending its temperature and humidity data. After these changes, the temperature data is read almost always right, the success rate is something like 90%. Im not sure can the modifications work with another system, but hopefully these kind of modifications can make other experiments more successful!
(p.s. I also made the eternal loop so that the class is created everytime over and over again when the method is called.)
add a comment |
up vote
0
down vote
I found that the RPi3b loaded with Raspian was too slow to use the code examples shown here already. Probably something to do with a java>pi4j>wiringpi propagation delay. My approach was as follows; after sending the command to activate the sensor, I read and time level changes on the required pin and save the values into an array. Then the parsing is done later. I get a 95% success rate with this code. I have it running in a Runnable class with a loop, so it has its own thread. If you find your timings are not quite right, try adjusting the counter offset. Also enable the println marked for debugging, it helps indicate which bits were not received (indicated by a 0).
public void scopeSensor(int pin){
int x = 0;
int lastState = 1;
int valueRead = 1;
int counter = 0;
int limit = 84;
int timeout = 0;
int results = new int[limit];
int pinState = new int[limit];
//set pin low for 18ms to request data
Gpio.pinMode(pin, Gpio.OUTPUT);
Gpio.digitalWrite(pin, Gpio.LOW);
Gpio.delay(18);
//get ready to recieve data back from dht11
Gpio.pinMode(pin, Gpio.INPUT);
Gpio.pullUpDnControl(pin, Gpio.PUD_UP); //activate internal pullup
while (x < limit) //84 sample changes to cover DHT11
{
timeout = 0;
counter = 2; //offset for time taken to perform read by pi
while (valueRead == lastState && timeout < 300){
Gpio.delayMicroseconds(1);
valueRead = Gpio.digitalRead(pin);
counter++;
timeout++;
}
if (timeout < 300)
{
results[x] = counter;
pinState[x] = lastState;
lastState = valueRead;
}
x++;
}
//reset our bytes
dht11_dat[0] = dht11_dat[1] =dht11_dat[2]=dht11_dat[3]=dht11_dat[4]=0;
int pointer = 0;
for (int i = 4; i<x; i=i+2){
//shift left so we are ready for next result
pointer = ((i-4) / 2) / 8;
dht11_dat[pointer] = dht11_dat[pointer] <<= 1;
//if more than 30, mark bit as 1
if (results[i] > 30){
dht11_dat[pointer] = dht11_dat[pointer] |= 1;
}
//for debugging only
// System.out.println(Integer.toString(pinState[i]) + "," + Integer.toString(results[i]));
}
int checksumByte = ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xff);
if (dht11_dat[4] != checksumByte){
System.out.println("Warning: Bad checksum value!");
}
System.out.println(" Temp: " + Integer.toString((dht11_dat[2])) + " RH: " + Integer.toString((dht11_dat[0])));
WriteToFile.writeTextToFile("RH-T.csv", Integer.toString((dht11_dat[0])) + "," + Integer.toString((dht11_dat[2])));
}
the run method:
@Override
public void run() {
ReadTempRH dht = new ReadTempRH();
while (NbSerialApp.runThreads){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(ReadTempRH.class.getName()).log(Level.SEVERE, null, ex);
}
//getTempRH(7);
scopeSensor(7);
}
}
ReadTempRH constructor:
private final int dht11_dat = {0,0,0,0,0};
public ReadTempRH() {
//setup wiringPi
if (Gpio.wiringPiSetup() == -1){
System.out.println("GPIO setup failed!");
return;
}
GpioUtil.export(3, GpioUtil.DIRECTION_OUT);
System.out.println("GPIO setup complete!");
}
Sorry my code is a little messy, I haven't had time to tidy things up! But you should get the idea. I am normally a c# guy and Netbeans doesn't work like VS in the tidying up front!
add a comment |
protected by Community♦ Dec 21 '16 at 23:12
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
accepted
I started with the original poster's java code, and replaced the com.pi4j.io.gpio package references with the com.pi4j.wiringpi package. I had recently installed the newest pi4j package and wiringpi version on my Raspberry Pi.
Using that package the Java code below works approximately the same as the c version of this program. I am getting about 80% - 85% accurate responses with a DHT-11. Which is about the same as I was getting using wiringPi in c.
package gpio;
import com.pi4j.wiringpi.Gpio;
import com.pi4j.wiringpi.GpioUtil;
public class DHT11 {
private static final int MAXTIMINGS = 85;
private final int dht11_dat = { 0, 0, 0, 0, 0 };
public DHT11() {
// setup wiringPi
if (Gpio.wiringPiSetup() == -1) {
System.out.println(" ==>> GPIO SETUP FAILED");
return;
}
GpioUtil.export(3, GpioUtil.DIRECTION_OUT);
}
public void getTemperature(final int pin) {
int laststate = Gpio.HIGH;
int j = 0;
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
Gpio.pinMode(pin, Gpio.OUTPUT);
Gpio.digitalWrite(pin, Gpio.LOW);
Gpio.delay(18);
Gpio.digitalWrite(pin, Gpio.HIGH);
Gpio.pinMode(pin, Gpio.INPUT);
for (int i = 0; i < MAXTIMINGS; i++) {
int counter = 0;
while (Gpio.digitalRead(pin) == laststate) {
counter++;
Gpio.delayMicroseconds(1);
if (counter == 255) {
break;
}
}
laststate = Gpio.digitalRead(pin);
if (counter == 255) {
break;
}
/* ignore first 3 transitions */
if (i >= 4 && i % 2 == 0) {
/* shove each bit into the storage bytes */
dht11_dat[j / 8] <<= 1;
if (counter > 16) {
dht11_dat[j / 8] |= 1;
}
j++;
}
}
// check we read 40 bits (8bit x 5 ) + verify checksum in the last
// byte
if (j >= 40 && checkParity()) {
float h = (float) ((dht11_dat[0] << 8) + dht11_dat[1]) / 10;
if (h > 100) {
h = dht11_dat[0]; // for DHT11
}
float c = (float) (((dht11_dat[2] & 0x7F) << 8) + dht11_dat[3]) / 10;
if (c > 125) {
c = dht11_dat[2]; // for DHT11
}
if ((dht11_dat[2] & 0x80) != 0) {
c = -c;
}
final float f = c * 1.8f + 32;
System.out.println("Humidity = " + h + " Temperature = " + c + "(" + f + "f)");
} else {
System.out.println("Data not good, skip");
}
}
private boolean checkParity() {
return dht11_dat[4] == (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3] & 0xFF);
}
public static void main(final String ars) throws Exception {
final DHT11 dht = new DHT11();
for (int i = 0; i < 10; i++) {
Thread.sleep(2000);
dht.getTemperature(21);
}
System.out.println("Done!!");
}
}
I have tried this, but the output is: "Data not good, skip"
– Dániel Kis
Nov 18 '16 at 22:20
This works for me, thanks a lot. I need ~25 reads (without delay) to get a valid value, but executed in a Loop this is no problem.
– Simulant
Mar 18 '17 at 23:36
Just out of curiosity: On which hardware type of Pi did you run this code?
– yglodt
Mar 26 '17 at 20:18
And another question: Do you think your code would also work for a DHT22 or AM2302?
– yglodt
Mar 26 '17 at 20:41
I used a Pi 2. I am not familiar with the DHT22 or AM2302, I have only tried it with the DHT11.
– Eric Smith
Mar 28 '17 at 2:12
|
show 4 more comments
up vote
7
down vote
accepted
I started with the original poster's java code, and replaced the com.pi4j.io.gpio package references with the com.pi4j.wiringpi package. I had recently installed the newest pi4j package and wiringpi version on my Raspberry Pi.
Using that package the Java code below works approximately the same as the c version of this program. I am getting about 80% - 85% accurate responses with a DHT-11. Which is about the same as I was getting using wiringPi in c.
package gpio;
import com.pi4j.wiringpi.Gpio;
import com.pi4j.wiringpi.GpioUtil;
public class DHT11 {
private static final int MAXTIMINGS = 85;
private final int dht11_dat = { 0, 0, 0, 0, 0 };
public DHT11() {
// setup wiringPi
if (Gpio.wiringPiSetup() == -1) {
System.out.println(" ==>> GPIO SETUP FAILED");
return;
}
GpioUtil.export(3, GpioUtil.DIRECTION_OUT);
}
public void getTemperature(final int pin) {
int laststate = Gpio.HIGH;
int j = 0;
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
Gpio.pinMode(pin, Gpio.OUTPUT);
Gpio.digitalWrite(pin, Gpio.LOW);
Gpio.delay(18);
Gpio.digitalWrite(pin, Gpio.HIGH);
Gpio.pinMode(pin, Gpio.INPUT);
for (int i = 0; i < MAXTIMINGS; i++) {
int counter = 0;
while (Gpio.digitalRead(pin) == laststate) {
counter++;
Gpio.delayMicroseconds(1);
if (counter == 255) {
break;
}
}
laststate = Gpio.digitalRead(pin);
if (counter == 255) {
break;
}
/* ignore first 3 transitions */
if (i >= 4 && i % 2 == 0) {
/* shove each bit into the storage bytes */
dht11_dat[j / 8] <<= 1;
if (counter > 16) {
dht11_dat[j / 8] |= 1;
}
j++;
}
}
// check we read 40 bits (8bit x 5 ) + verify checksum in the last
// byte
if (j >= 40 && checkParity()) {
float h = (float) ((dht11_dat[0] << 8) + dht11_dat[1]) / 10;
if (h > 100) {
h = dht11_dat[0]; // for DHT11
}
float c = (float) (((dht11_dat[2] & 0x7F) << 8) + dht11_dat[3]) / 10;
if (c > 125) {
c = dht11_dat[2]; // for DHT11
}
if ((dht11_dat[2] & 0x80) != 0) {
c = -c;
}
final float f = c * 1.8f + 32;
System.out.println("Humidity = " + h + " Temperature = " + c + "(" + f + "f)");
} else {
System.out.println("Data not good, skip");
}
}
private boolean checkParity() {
return dht11_dat[4] == (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3] & 0xFF);
}
public static void main(final String ars) throws Exception {
final DHT11 dht = new DHT11();
for (int i = 0; i < 10; i++) {
Thread.sleep(2000);
dht.getTemperature(21);
}
System.out.println("Done!!");
}
}
I have tried this, but the output is: "Data not good, skip"
– Dániel Kis
Nov 18 '16 at 22:20
This works for me, thanks a lot. I need ~25 reads (without delay) to get a valid value, but executed in a Loop this is no problem.
– Simulant
Mar 18 '17 at 23:36
Just out of curiosity: On which hardware type of Pi did you run this code?
– yglodt
Mar 26 '17 at 20:18
And another question: Do you think your code would also work for a DHT22 or AM2302?
– yglodt
Mar 26 '17 at 20:41
I used a Pi 2. I am not familiar with the DHT22 or AM2302, I have only tried it with the DHT11.
– Eric Smith
Mar 28 '17 at 2:12
|
show 4 more comments
up vote
7
down vote
accepted
up vote
7
down vote
accepted
I started with the original poster's java code, and replaced the com.pi4j.io.gpio package references with the com.pi4j.wiringpi package. I had recently installed the newest pi4j package and wiringpi version on my Raspberry Pi.
Using that package the Java code below works approximately the same as the c version of this program. I am getting about 80% - 85% accurate responses with a DHT-11. Which is about the same as I was getting using wiringPi in c.
package gpio;
import com.pi4j.wiringpi.Gpio;
import com.pi4j.wiringpi.GpioUtil;
public class DHT11 {
private static final int MAXTIMINGS = 85;
private final int dht11_dat = { 0, 0, 0, 0, 0 };
public DHT11() {
// setup wiringPi
if (Gpio.wiringPiSetup() == -1) {
System.out.println(" ==>> GPIO SETUP FAILED");
return;
}
GpioUtil.export(3, GpioUtil.DIRECTION_OUT);
}
public void getTemperature(final int pin) {
int laststate = Gpio.HIGH;
int j = 0;
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
Gpio.pinMode(pin, Gpio.OUTPUT);
Gpio.digitalWrite(pin, Gpio.LOW);
Gpio.delay(18);
Gpio.digitalWrite(pin, Gpio.HIGH);
Gpio.pinMode(pin, Gpio.INPUT);
for (int i = 0; i < MAXTIMINGS; i++) {
int counter = 0;
while (Gpio.digitalRead(pin) == laststate) {
counter++;
Gpio.delayMicroseconds(1);
if (counter == 255) {
break;
}
}
laststate = Gpio.digitalRead(pin);
if (counter == 255) {
break;
}
/* ignore first 3 transitions */
if (i >= 4 && i % 2 == 0) {
/* shove each bit into the storage bytes */
dht11_dat[j / 8] <<= 1;
if (counter > 16) {
dht11_dat[j / 8] |= 1;
}
j++;
}
}
// check we read 40 bits (8bit x 5 ) + verify checksum in the last
// byte
if (j >= 40 && checkParity()) {
float h = (float) ((dht11_dat[0] << 8) + dht11_dat[1]) / 10;
if (h > 100) {
h = dht11_dat[0]; // for DHT11
}
float c = (float) (((dht11_dat[2] & 0x7F) << 8) + dht11_dat[3]) / 10;
if (c > 125) {
c = dht11_dat[2]; // for DHT11
}
if ((dht11_dat[2] & 0x80) != 0) {
c = -c;
}
final float f = c * 1.8f + 32;
System.out.println("Humidity = " + h + " Temperature = " + c + "(" + f + "f)");
} else {
System.out.println("Data not good, skip");
}
}
private boolean checkParity() {
return dht11_dat[4] == (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3] & 0xFF);
}
public static void main(final String ars) throws Exception {
final DHT11 dht = new DHT11();
for (int i = 0; i < 10; i++) {
Thread.sleep(2000);
dht.getTemperature(21);
}
System.out.println("Done!!");
}
}
I started with the original poster's java code, and replaced the com.pi4j.io.gpio package references with the com.pi4j.wiringpi package. I had recently installed the newest pi4j package and wiringpi version on my Raspberry Pi.
Using that package the Java code below works approximately the same as the c version of this program. I am getting about 80% - 85% accurate responses with a DHT-11. Which is about the same as I was getting using wiringPi in c.
package gpio;
import com.pi4j.wiringpi.Gpio;
import com.pi4j.wiringpi.GpioUtil;
public class DHT11 {
private static final int MAXTIMINGS = 85;
private final int dht11_dat = { 0, 0, 0, 0, 0 };
public DHT11() {
// setup wiringPi
if (Gpio.wiringPiSetup() == -1) {
System.out.println(" ==>> GPIO SETUP FAILED");
return;
}
GpioUtil.export(3, GpioUtil.DIRECTION_OUT);
}
public void getTemperature(final int pin) {
int laststate = Gpio.HIGH;
int j = 0;
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
Gpio.pinMode(pin, Gpio.OUTPUT);
Gpio.digitalWrite(pin, Gpio.LOW);
Gpio.delay(18);
Gpio.digitalWrite(pin, Gpio.HIGH);
Gpio.pinMode(pin, Gpio.INPUT);
for (int i = 0; i < MAXTIMINGS; i++) {
int counter = 0;
while (Gpio.digitalRead(pin) == laststate) {
counter++;
Gpio.delayMicroseconds(1);
if (counter == 255) {
break;
}
}
laststate = Gpio.digitalRead(pin);
if (counter == 255) {
break;
}
/* ignore first 3 transitions */
if (i >= 4 && i % 2 == 0) {
/* shove each bit into the storage bytes */
dht11_dat[j / 8] <<= 1;
if (counter > 16) {
dht11_dat[j / 8] |= 1;
}
j++;
}
}
// check we read 40 bits (8bit x 5 ) + verify checksum in the last
// byte
if (j >= 40 && checkParity()) {
float h = (float) ((dht11_dat[0] << 8) + dht11_dat[1]) / 10;
if (h > 100) {
h = dht11_dat[0]; // for DHT11
}
float c = (float) (((dht11_dat[2] & 0x7F) << 8) + dht11_dat[3]) / 10;
if (c > 125) {
c = dht11_dat[2]; // for DHT11
}
if ((dht11_dat[2] & 0x80) != 0) {
c = -c;
}
final float f = c * 1.8f + 32;
System.out.println("Humidity = " + h + " Temperature = " + c + "(" + f + "f)");
} else {
System.out.println("Data not good, skip");
}
}
private boolean checkParity() {
return dht11_dat[4] == (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3] & 0xFF);
}
public static void main(final String ars) throws Exception {
final DHT11 dht = new DHT11();
for (int i = 0; i < 10; i++) {
Thread.sleep(2000);
dht.getTemperature(21);
}
System.out.println("Done!!");
}
}
edited Mar 26 '17 at 20:43
yglodt
6,42064581
6,42064581
answered Jan 24 '16 at 13:52
Eric Smith
11316
11316
I have tried this, but the output is: "Data not good, skip"
– Dániel Kis
Nov 18 '16 at 22:20
This works for me, thanks a lot. I need ~25 reads (without delay) to get a valid value, but executed in a Loop this is no problem.
– Simulant
Mar 18 '17 at 23:36
Just out of curiosity: On which hardware type of Pi did you run this code?
– yglodt
Mar 26 '17 at 20:18
And another question: Do you think your code would also work for a DHT22 or AM2302?
– yglodt
Mar 26 '17 at 20:41
I used a Pi 2. I am not familiar with the DHT22 or AM2302, I have only tried it with the DHT11.
– Eric Smith
Mar 28 '17 at 2:12
|
show 4 more comments
I have tried this, but the output is: "Data not good, skip"
– Dániel Kis
Nov 18 '16 at 22:20
This works for me, thanks a lot. I need ~25 reads (without delay) to get a valid value, but executed in a Loop this is no problem.
– Simulant
Mar 18 '17 at 23:36
Just out of curiosity: On which hardware type of Pi did you run this code?
– yglodt
Mar 26 '17 at 20:18
And another question: Do you think your code would also work for a DHT22 or AM2302?
– yglodt
Mar 26 '17 at 20:41
I used a Pi 2. I am not familiar with the DHT22 or AM2302, I have only tried it with the DHT11.
– Eric Smith
Mar 28 '17 at 2:12
I have tried this, but the output is: "Data not good, skip"
– Dániel Kis
Nov 18 '16 at 22:20
I have tried this, but the output is: "Data not good, skip"
– Dániel Kis
Nov 18 '16 at 22:20
This works for me, thanks a lot. I need ~25 reads (without delay) to get a valid value, but executed in a Loop this is no problem.
– Simulant
Mar 18 '17 at 23:36
This works for me, thanks a lot. I need ~25 reads (without delay) to get a valid value, but executed in a Loop this is no problem.
– Simulant
Mar 18 '17 at 23:36
Just out of curiosity: On which hardware type of Pi did you run this code?
– yglodt
Mar 26 '17 at 20:18
Just out of curiosity: On which hardware type of Pi did you run this code?
– yglodt
Mar 26 '17 at 20:18
And another question: Do you think your code would also work for a DHT22 or AM2302?
– yglodt
Mar 26 '17 at 20:41
And another question: Do you think your code would also work for a DHT22 or AM2302?
– yglodt
Mar 26 '17 at 20:41
I used a Pi 2. I am not familiar with the DHT22 or AM2302, I have only tried it with the DHT11.
– Eric Smith
Mar 28 '17 at 2:12
I used a Pi 2. I am not familiar with the DHT22 or AM2302, I have only tried it with the DHT11.
– Eric Smith
Mar 28 '17 at 2:12
|
show 4 more comments
up vote
0
down vote
If you're always getting a High State it might be good to double check if the wiring is correct (or if any of the wires are broken, test it with a led).
I've used adafruit's tutorial in C and python and it worked on my DHT22.
add a comment |
up vote
0
down vote
If you're always getting a High State it might be good to double check if the wiring is correct (or if any of the wires are broken, test it with a led).
I've used adafruit's tutorial in C and python and it worked on my DHT22.
add a comment |
up vote
0
down vote
up vote
0
down vote
If you're always getting a High State it might be good to double check if the wiring is correct (or if any of the wires are broken, test it with a led).
I've used adafruit's tutorial in C and python and it worked on my DHT22.
If you're always getting a High State it might be good to double check if the wiring is correct (or if any of the wires are broken, test it with a led).
I've used adafruit's tutorial in C and python and it worked on my DHT22.
answered Feb 15 '15 at 12:24
Txugo
2,20142736
2,20142736
add a comment |
add a comment |
up vote
0
down vote
I've the same issue and, unfortunately, I've read that Java cannot read data from DHT11/22 in this way for timing problems.
I've found in the Raspberry Forum a thread where you can find some solutions using SPI or pigpio.
Another full Java possible solution is there.
I've received my sensor yesterday and I have not already tried this solutions. When I'll try, I'll let you know.
[EDIT]
Hi, I've solved the problem calling a python script (which uses the Adafruit Driver) and reading it's output.
The python script is simply the example published in the Adafruit's library. I've only changed the output at line 48 in
print '{0:0.1f} {1:0.1f}'.format(temperature, humidity)
The Java method that updates the values with new values is:
public void update() {
String cmd = "sudo python DHTReader.py 11 4";
try {
String ret = "";
try {
String line;
Process p = Runtime.getRuntime().exec(cmd.split(" "));
p.waitFor();
BufferedReader input = new BufferedReader
(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output += (line + 'n');
}
input.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
ret.trim();
if (ret.length() == 0) // Library is not present
throw new RuntimeException(LIB_NOT_PRESENT_MESSAGE);
else{
// Error reading the the sensor, maybe is not connected.
if(ret.contains(ERROR_READING)){
String msg = String.format(ERROR_READING_MSG,toString());
throw new Exception(msg);
}
else{
// Read completed. Parse and update the values
String vals = ret.split(" ");
float t = Float.parseFloat(vals[0].trim());
float h = Float.parseFloat(vals[1].trim());
if( (t != lastTemp) || (h != lastHum) ){
lastUpdate = new Date();
lastTemp = t;
lastHum = h;
}
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
if( e instanceof RuntimeException)
System.exit(-1);
}
}
To make it work you have to install the Adafruit library as described in the linked page and change DHTReader.py with the path of the scipt.
I'm working to build a "library". If you need, when I've finished, I'll publish it on GitHub.
add a comment |
up vote
0
down vote
I've the same issue and, unfortunately, I've read that Java cannot read data from DHT11/22 in this way for timing problems.
I've found in the Raspberry Forum a thread where you can find some solutions using SPI or pigpio.
Another full Java possible solution is there.
I've received my sensor yesterday and I have not already tried this solutions. When I'll try, I'll let you know.
[EDIT]
Hi, I've solved the problem calling a python script (which uses the Adafruit Driver) and reading it's output.
The python script is simply the example published in the Adafruit's library. I've only changed the output at line 48 in
print '{0:0.1f} {1:0.1f}'.format(temperature, humidity)
The Java method that updates the values with new values is:
public void update() {
String cmd = "sudo python DHTReader.py 11 4";
try {
String ret = "";
try {
String line;
Process p = Runtime.getRuntime().exec(cmd.split(" "));
p.waitFor();
BufferedReader input = new BufferedReader
(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output += (line + 'n');
}
input.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
ret.trim();
if (ret.length() == 0) // Library is not present
throw new RuntimeException(LIB_NOT_PRESENT_MESSAGE);
else{
// Error reading the the sensor, maybe is not connected.
if(ret.contains(ERROR_READING)){
String msg = String.format(ERROR_READING_MSG,toString());
throw new Exception(msg);
}
else{
// Read completed. Parse and update the values
String vals = ret.split(" ");
float t = Float.parseFloat(vals[0].trim());
float h = Float.parseFloat(vals[1].trim());
if( (t != lastTemp) || (h != lastHum) ){
lastUpdate = new Date();
lastTemp = t;
lastHum = h;
}
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
if( e instanceof RuntimeException)
System.exit(-1);
}
}
To make it work you have to install the Adafruit library as described in the linked page and change DHTReader.py with the path of the scipt.
I'm working to build a "library". If you need, when I've finished, I'll publish it on GitHub.
add a comment |
up vote
0
down vote
up vote
0
down vote
I've the same issue and, unfortunately, I've read that Java cannot read data from DHT11/22 in this way for timing problems.
I've found in the Raspberry Forum a thread where you can find some solutions using SPI or pigpio.
Another full Java possible solution is there.
I've received my sensor yesterday and I have not already tried this solutions. When I'll try, I'll let you know.
[EDIT]
Hi, I've solved the problem calling a python script (which uses the Adafruit Driver) and reading it's output.
The python script is simply the example published in the Adafruit's library. I've only changed the output at line 48 in
print '{0:0.1f} {1:0.1f}'.format(temperature, humidity)
The Java method that updates the values with new values is:
public void update() {
String cmd = "sudo python DHTReader.py 11 4";
try {
String ret = "";
try {
String line;
Process p = Runtime.getRuntime().exec(cmd.split(" "));
p.waitFor();
BufferedReader input = new BufferedReader
(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output += (line + 'n');
}
input.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
ret.trim();
if (ret.length() == 0) // Library is not present
throw new RuntimeException(LIB_NOT_PRESENT_MESSAGE);
else{
// Error reading the the sensor, maybe is not connected.
if(ret.contains(ERROR_READING)){
String msg = String.format(ERROR_READING_MSG,toString());
throw new Exception(msg);
}
else{
// Read completed. Parse and update the values
String vals = ret.split(" ");
float t = Float.parseFloat(vals[0].trim());
float h = Float.parseFloat(vals[1].trim());
if( (t != lastTemp) || (h != lastHum) ){
lastUpdate = new Date();
lastTemp = t;
lastHum = h;
}
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
if( e instanceof RuntimeException)
System.exit(-1);
}
}
To make it work you have to install the Adafruit library as described in the linked page and change DHTReader.py with the path of the scipt.
I'm working to build a "library". If you need, when I've finished, I'll publish it on GitHub.
I've the same issue and, unfortunately, I've read that Java cannot read data from DHT11/22 in this way for timing problems.
I've found in the Raspberry Forum a thread where you can find some solutions using SPI or pigpio.
Another full Java possible solution is there.
I've received my sensor yesterday and I have not already tried this solutions. When I'll try, I'll let you know.
[EDIT]
Hi, I've solved the problem calling a python script (which uses the Adafruit Driver) and reading it's output.
The python script is simply the example published in the Adafruit's library. I've only changed the output at line 48 in
print '{0:0.1f} {1:0.1f}'.format(temperature, humidity)
The Java method that updates the values with new values is:
public void update() {
String cmd = "sudo python DHTReader.py 11 4";
try {
String ret = "";
try {
String line;
Process p = Runtime.getRuntime().exec(cmd.split(" "));
p.waitFor();
BufferedReader input = new BufferedReader
(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output += (line + 'n');
}
input.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
ret.trim();
if (ret.length() == 0) // Library is not present
throw new RuntimeException(LIB_NOT_PRESENT_MESSAGE);
else{
// Error reading the the sensor, maybe is not connected.
if(ret.contains(ERROR_READING)){
String msg = String.format(ERROR_READING_MSG,toString());
throw new Exception(msg);
}
else{
// Read completed. Parse and update the values
String vals = ret.split(" ");
float t = Float.parseFloat(vals[0].trim());
float h = Float.parseFloat(vals[1].trim());
if( (t != lastTemp) || (h != lastHum) ){
lastUpdate = new Date();
lastTemp = t;
lastHum = h;
}
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
if( e instanceof RuntimeException)
System.exit(-1);
}
}
To make it work you have to install the Adafruit library as described in the linked page and change DHTReader.py with the path of the scipt.
I'm working to build a "library". If you need, when I've finished, I'll publish it on GitHub.
edited Mar 2 '15 at 19:47
answered Feb 14 '15 at 14:02
Carlo
92
92
add a comment |
add a comment |
up vote
0
down vote
I got a solution with Java Native Interface JNI and WiringPi.
I am using java openjdk 7 in the raspberry pi. This is important to for support JNI capabilites of the JVM. I connected the DHT11 sensor to GPIO1 or pin 1.
From the package root at src/main/java you can install the library. I prepared a script in that you can run with the command:
sudo sh jniDHT11SensorReaderBuilder.sh
Then to test if it works try to run the DHT11SensorReader class with the command
sudo java org.mandfer.dht11.DHT11SensorReader
If it is all fine and you want more values every 1.5 seconds try to run the exercise 20 from the project root folder.
sh runPi.sh org.mandfer.sunfunpi4j.Ex20_DHT11_Native
If you have any issue, leave me a comment.
I hope it helps.
Marc Andreu,
I am not able to compile this lib, Multiple errors first wiringpi.h not found, then no jni file. Can you give me workable script to get .so file for android
– Manoj
Jun 15 '17 at 11:03
Hello Manoj, did you try with the script jniDHT11SensorReaderBuilder.sh ? Make sure you are actually running JAVA OpenJDK 1.7 and run it from folder "src/main/java/" in the raspberry pi. Also follow make sure that you installed Pi4j and the wiringpi libs for your version of raspberry pi
– marcandreuf
Jun 16 '17 at 15:32
add a comment |
up vote
0
down vote
I got a solution with Java Native Interface JNI and WiringPi.
I am using java openjdk 7 in the raspberry pi. This is important to for support JNI capabilites of the JVM. I connected the DHT11 sensor to GPIO1 or pin 1.
From the package root at src/main/java you can install the library. I prepared a script in that you can run with the command:
sudo sh jniDHT11SensorReaderBuilder.sh
Then to test if it works try to run the DHT11SensorReader class with the command
sudo java org.mandfer.dht11.DHT11SensorReader
If it is all fine and you want more values every 1.5 seconds try to run the exercise 20 from the project root folder.
sh runPi.sh org.mandfer.sunfunpi4j.Ex20_DHT11_Native
If you have any issue, leave me a comment.
I hope it helps.
Marc Andreu,
I am not able to compile this lib, Multiple errors first wiringpi.h not found, then no jni file. Can you give me workable script to get .so file for android
– Manoj
Jun 15 '17 at 11:03
Hello Manoj, did you try with the script jniDHT11SensorReaderBuilder.sh ? Make sure you are actually running JAVA OpenJDK 1.7 and run it from folder "src/main/java/" in the raspberry pi. Also follow make sure that you installed Pi4j and the wiringpi libs for your version of raspberry pi
– marcandreuf
Jun 16 '17 at 15:32
add a comment |
up vote
0
down vote
up vote
0
down vote
I got a solution with Java Native Interface JNI and WiringPi.
I am using java openjdk 7 in the raspberry pi. This is important to for support JNI capabilites of the JVM. I connected the DHT11 sensor to GPIO1 or pin 1.
From the package root at src/main/java you can install the library. I prepared a script in that you can run with the command:
sudo sh jniDHT11SensorReaderBuilder.sh
Then to test if it works try to run the DHT11SensorReader class with the command
sudo java org.mandfer.dht11.DHT11SensorReader
If it is all fine and you want more values every 1.5 seconds try to run the exercise 20 from the project root folder.
sh runPi.sh org.mandfer.sunfunpi4j.Ex20_DHT11_Native
If you have any issue, leave me a comment.
I hope it helps.
Marc Andreu,
I got a solution with Java Native Interface JNI and WiringPi.
I am using java openjdk 7 in the raspberry pi. This is important to for support JNI capabilites of the JVM. I connected the DHT11 sensor to GPIO1 or pin 1.
From the package root at src/main/java you can install the library. I prepared a script in that you can run with the command:
sudo sh jniDHT11SensorReaderBuilder.sh
Then to test if it works try to run the DHT11SensorReader class with the command
sudo java org.mandfer.dht11.DHT11SensorReader
If it is all fine and you want more values every 1.5 seconds try to run the exercise 20 from the project root folder.
sh runPi.sh org.mandfer.sunfunpi4j.Ex20_DHT11_Native
If you have any issue, leave me a comment.
I hope it helps.
Marc Andreu,
answered Jun 7 '15 at 21:51
community wiki
marcandreuf
I am not able to compile this lib, Multiple errors first wiringpi.h not found, then no jni file. Can you give me workable script to get .so file for android
– Manoj
Jun 15 '17 at 11:03
Hello Manoj, did you try with the script jniDHT11SensorReaderBuilder.sh ? Make sure you are actually running JAVA OpenJDK 1.7 and run it from folder "src/main/java/" in the raspberry pi. Also follow make sure that you installed Pi4j and the wiringpi libs for your version of raspberry pi
– marcandreuf
Jun 16 '17 at 15:32
add a comment |
I am not able to compile this lib, Multiple errors first wiringpi.h not found, then no jni file. Can you give me workable script to get .so file for android
– Manoj
Jun 15 '17 at 11:03
Hello Manoj, did you try with the script jniDHT11SensorReaderBuilder.sh ? Make sure you are actually running JAVA OpenJDK 1.7 and run it from folder "src/main/java/" in the raspberry pi. Also follow make sure that you installed Pi4j and the wiringpi libs for your version of raspberry pi
– marcandreuf
Jun 16 '17 at 15:32
I am not able to compile this lib, Multiple errors first wiringpi.h not found, then no jni file. Can you give me workable script to get .so file for android
– Manoj
Jun 15 '17 at 11:03
I am not able to compile this lib, Multiple errors first wiringpi.h not found, then no jni file. Can you give me workable script to get .so file for android
– Manoj
Jun 15 '17 at 11:03
Hello Manoj, did you try with the script jniDHT11SensorReaderBuilder.sh ? Make sure you are actually running JAVA OpenJDK 1.7 and run it from folder "src/main/java/" in the raspberry pi. Also follow make sure that you installed Pi4j and the wiringpi libs for your version of raspberry pi
– marcandreuf
Jun 16 '17 at 15:32
Hello Manoj, did you try with the script jniDHT11SensorReaderBuilder.sh ? Make sure you are actually running JAVA OpenJDK 1.7 and run it from folder "src/main/java/" in the raspberry pi. Also follow make sure that you installed Pi4j and the wiringpi libs for your version of raspberry pi
– marcandreuf
Jun 16 '17 at 15:32
add a comment |
up vote
0
down vote
Eric Smith's excellent code works fine for me with two small mods, First I edited this line:
if (counter > 16)
To:
if (counter > 30)
According to specs of dht11, the "1" bit is transmitted when the delay of the "Gpio.HIGH" is about 70us, and "0" bit is transmitted if the delay is 26-28us. It is clear that Java takes some time to execute, so it is safe to assume that if the delay is more than 30us the data must be "1". But this might be different value if the execution time of Java program is different in your machine (perhaps the processor of pi is faster/slower, there is more background programs etc). Therefore, the 30 is not necessarily the right value for every situation.
According to specs 1, it can be also noted that sender (raspberry pi, called MCU in the specs), should also send Gpio.HIGH for at least 18ms. After that, the MCU should send 20-40 us "Gpio.HIGH". I tested with System.nanoTime() how much time it takes for the Java to execute setting the Gpio.Pinmode to the "Input". It took something like 20us, so I added:
Gpio.delayMicroseconds(7);
...just to be sure that the Pin is HIGH for at least 20us so that the Sensor can register that signal and start sending its temperature and humidity data. After these changes, the temperature data is read almost always right, the success rate is something like 90%. Im not sure can the modifications work with another system, but hopefully these kind of modifications can make other experiments more successful!
(p.s. I also made the eternal loop so that the class is created everytime over and over again when the method is called.)
add a comment |
up vote
0
down vote
Eric Smith's excellent code works fine for me with two small mods, First I edited this line:
if (counter > 16)
To:
if (counter > 30)
According to specs of dht11, the "1" bit is transmitted when the delay of the "Gpio.HIGH" is about 70us, and "0" bit is transmitted if the delay is 26-28us. It is clear that Java takes some time to execute, so it is safe to assume that if the delay is more than 30us the data must be "1". But this might be different value if the execution time of Java program is different in your machine (perhaps the processor of pi is faster/slower, there is more background programs etc). Therefore, the 30 is not necessarily the right value for every situation.
According to specs 1, it can be also noted that sender (raspberry pi, called MCU in the specs), should also send Gpio.HIGH for at least 18ms. After that, the MCU should send 20-40 us "Gpio.HIGH". I tested with System.nanoTime() how much time it takes for the Java to execute setting the Gpio.Pinmode to the "Input". It took something like 20us, so I added:
Gpio.delayMicroseconds(7);
...just to be sure that the Pin is HIGH for at least 20us so that the Sensor can register that signal and start sending its temperature and humidity data. After these changes, the temperature data is read almost always right, the success rate is something like 90%. Im not sure can the modifications work with another system, but hopefully these kind of modifications can make other experiments more successful!
(p.s. I also made the eternal loop so that the class is created everytime over and over again when the method is called.)
add a comment |
up vote
0
down vote
up vote
0
down vote
Eric Smith's excellent code works fine for me with two small mods, First I edited this line:
if (counter > 16)
To:
if (counter > 30)
According to specs of dht11, the "1" bit is transmitted when the delay of the "Gpio.HIGH" is about 70us, and "0" bit is transmitted if the delay is 26-28us. It is clear that Java takes some time to execute, so it is safe to assume that if the delay is more than 30us the data must be "1". But this might be different value if the execution time of Java program is different in your machine (perhaps the processor of pi is faster/slower, there is more background programs etc). Therefore, the 30 is not necessarily the right value for every situation.
According to specs 1, it can be also noted that sender (raspberry pi, called MCU in the specs), should also send Gpio.HIGH for at least 18ms. After that, the MCU should send 20-40 us "Gpio.HIGH". I tested with System.nanoTime() how much time it takes for the Java to execute setting the Gpio.Pinmode to the "Input". It took something like 20us, so I added:
Gpio.delayMicroseconds(7);
...just to be sure that the Pin is HIGH for at least 20us so that the Sensor can register that signal and start sending its temperature and humidity data. After these changes, the temperature data is read almost always right, the success rate is something like 90%. Im not sure can the modifications work with another system, but hopefully these kind of modifications can make other experiments more successful!
(p.s. I also made the eternal loop so that the class is created everytime over and over again when the method is called.)
Eric Smith's excellent code works fine for me with two small mods, First I edited this line:
if (counter > 16)
To:
if (counter > 30)
According to specs of dht11, the "1" bit is transmitted when the delay of the "Gpio.HIGH" is about 70us, and "0" bit is transmitted if the delay is 26-28us. It is clear that Java takes some time to execute, so it is safe to assume that if the delay is more than 30us the data must be "1". But this might be different value if the execution time of Java program is different in your machine (perhaps the processor of pi is faster/slower, there is more background programs etc). Therefore, the 30 is not necessarily the right value for every situation.
According to specs 1, it can be also noted that sender (raspberry pi, called MCU in the specs), should also send Gpio.HIGH for at least 18ms. After that, the MCU should send 20-40 us "Gpio.HIGH". I tested with System.nanoTime() how much time it takes for the Java to execute setting the Gpio.Pinmode to the "Input". It took something like 20us, so I added:
Gpio.delayMicroseconds(7);
...just to be sure that the Pin is HIGH for at least 20us so that the Sensor can register that signal and start sending its temperature and humidity data. After these changes, the temperature data is read almost always right, the success rate is something like 90%. Im not sure can the modifications work with another system, but hopefully these kind of modifications can make other experiments more successful!
(p.s. I also made the eternal loop so that the class is created everytime over and over again when the method is called.)
answered Dec 16 '17 at 17:42
iltelko
378
378
add a comment |
add a comment |
up vote
0
down vote
I found that the RPi3b loaded with Raspian was too slow to use the code examples shown here already. Probably something to do with a java>pi4j>wiringpi propagation delay. My approach was as follows; after sending the command to activate the sensor, I read and time level changes on the required pin and save the values into an array. Then the parsing is done later. I get a 95% success rate with this code. I have it running in a Runnable class with a loop, so it has its own thread. If you find your timings are not quite right, try adjusting the counter offset. Also enable the println marked for debugging, it helps indicate which bits were not received (indicated by a 0).
public void scopeSensor(int pin){
int x = 0;
int lastState = 1;
int valueRead = 1;
int counter = 0;
int limit = 84;
int timeout = 0;
int results = new int[limit];
int pinState = new int[limit];
//set pin low for 18ms to request data
Gpio.pinMode(pin, Gpio.OUTPUT);
Gpio.digitalWrite(pin, Gpio.LOW);
Gpio.delay(18);
//get ready to recieve data back from dht11
Gpio.pinMode(pin, Gpio.INPUT);
Gpio.pullUpDnControl(pin, Gpio.PUD_UP); //activate internal pullup
while (x < limit) //84 sample changes to cover DHT11
{
timeout = 0;
counter = 2; //offset for time taken to perform read by pi
while (valueRead == lastState && timeout < 300){
Gpio.delayMicroseconds(1);
valueRead = Gpio.digitalRead(pin);
counter++;
timeout++;
}
if (timeout < 300)
{
results[x] = counter;
pinState[x] = lastState;
lastState = valueRead;
}
x++;
}
//reset our bytes
dht11_dat[0] = dht11_dat[1] =dht11_dat[2]=dht11_dat[3]=dht11_dat[4]=0;
int pointer = 0;
for (int i = 4; i<x; i=i+2){
//shift left so we are ready for next result
pointer = ((i-4) / 2) / 8;
dht11_dat[pointer] = dht11_dat[pointer] <<= 1;
//if more than 30, mark bit as 1
if (results[i] > 30){
dht11_dat[pointer] = dht11_dat[pointer] |= 1;
}
//for debugging only
// System.out.println(Integer.toString(pinState[i]) + "," + Integer.toString(results[i]));
}
int checksumByte = ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xff);
if (dht11_dat[4] != checksumByte){
System.out.println("Warning: Bad checksum value!");
}
System.out.println(" Temp: " + Integer.toString((dht11_dat[2])) + " RH: " + Integer.toString((dht11_dat[0])));
WriteToFile.writeTextToFile("RH-T.csv", Integer.toString((dht11_dat[0])) + "," + Integer.toString((dht11_dat[2])));
}
the run method:
@Override
public void run() {
ReadTempRH dht = new ReadTempRH();
while (NbSerialApp.runThreads){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(ReadTempRH.class.getName()).log(Level.SEVERE, null, ex);
}
//getTempRH(7);
scopeSensor(7);
}
}
ReadTempRH constructor:
private final int dht11_dat = {0,0,0,0,0};
public ReadTempRH() {
//setup wiringPi
if (Gpio.wiringPiSetup() == -1){
System.out.println("GPIO setup failed!");
return;
}
GpioUtil.export(3, GpioUtil.DIRECTION_OUT);
System.out.println("GPIO setup complete!");
}
Sorry my code is a little messy, I haven't had time to tidy things up! But you should get the idea. I am normally a c# guy and Netbeans doesn't work like VS in the tidying up front!
add a comment |
up vote
0
down vote
I found that the RPi3b loaded with Raspian was too slow to use the code examples shown here already. Probably something to do with a java>pi4j>wiringpi propagation delay. My approach was as follows; after sending the command to activate the sensor, I read and time level changes on the required pin and save the values into an array. Then the parsing is done later. I get a 95% success rate with this code. I have it running in a Runnable class with a loop, so it has its own thread. If you find your timings are not quite right, try adjusting the counter offset. Also enable the println marked for debugging, it helps indicate which bits were not received (indicated by a 0).
public void scopeSensor(int pin){
int x = 0;
int lastState = 1;
int valueRead = 1;
int counter = 0;
int limit = 84;
int timeout = 0;
int results = new int[limit];
int pinState = new int[limit];
//set pin low for 18ms to request data
Gpio.pinMode(pin, Gpio.OUTPUT);
Gpio.digitalWrite(pin, Gpio.LOW);
Gpio.delay(18);
//get ready to recieve data back from dht11
Gpio.pinMode(pin, Gpio.INPUT);
Gpio.pullUpDnControl(pin, Gpio.PUD_UP); //activate internal pullup
while (x < limit) //84 sample changes to cover DHT11
{
timeout = 0;
counter = 2; //offset for time taken to perform read by pi
while (valueRead == lastState && timeout < 300){
Gpio.delayMicroseconds(1);
valueRead = Gpio.digitalRead(pin);
counter++;
timeout++;
}
if (timeout < 300)
{
results[x] = counter;
pinState[x] = lastState;
lastState = valueRead;
}
x++;
}
//reset our bytes
dht11_dat[0] = dht11_dat[1] =dht11_dat[2]=dht11_dat[3]=dht11_dat[4]=0;
int pointer = 0;
for (int i = 4; i<x; i=i+2){
//shift left so we are ready for next result
pointer = ((i-4) / 2) / 8;
dht11_dat[pointer] = dht11_dat[pointer] <<= 1;
//if more than 30, mark bit as 1
if (results[i] > 30){
dht11_dat[pointer] = dht11_dat[pointer] |= 1;
}
//for debugging only
// System.out.println(Integer.toString(pinState[i]) + "," + Integer.toString(results[i]));
}
int checksumByte = ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xff);
if (dht11_dat[4] != checksumByte){
System.out.println("Warning: Bad checksum value!");
}
System.out.println(" Temp: " + Integer.toString((dht11_dat[2])) + " RH: " + Integer.toString((dht11_dat[0])));
WriteToFile.writeTextToFile("RH-T.csv", Integer.toString((dht11_dat[0])) + "," + Integer.toString((dht11_dat[2])));
}
the run method:
@Override
public void run() {
ReadTempRH dht = new ReadTempRH();
while (NbSerialApp.runThreads){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(ReadTempRH.class.getName()).log(Level.SEVERE, null, ex);
}
//getTempRH(7);
scopeSensor(7);
}
}
ReadTempRH constructor:
private final int dht11_dat = {0,0,0,0,0};
public ReadTempRH() {
//setup wiringPi
if (Gpio.wiringPiSetup() == -1){
System.out.println("GPIO setup failed!");
return;
}
GpioUtil.export(3, GpioUtil.DIRECTION_OUT);
System.out.println("GPIO setup complete!");
}
Sorry my code is a little messy, I haven't had time to tidy things up! But you should get the idea. I am normally a c# guy and Netbeans doesn't work like VS in the tidying up front!
add a comment |
up vote
0
down vote
up vote
0
down vote
I found that the RPi3b loaded with Raspian was too slow to use the code examples shown here already. Probably something to do with a java>pi4j>wiringpi propagation delay. My approach was as follows; after sending the command to activate the sensor, I read and time level changes on the required pin and save the values into an array. Then the parsing is done later. I get a 95% success rate with this code. I have it running in a Runnable class with a loop, so it has its own thread. If you find your timings are not quite right, try adjusting the counter offset. Also enable the println marked for debugging, it helps indicate which bits were not received (indicated by a 0).
public void scopeSensor(int pin){
int x = 0;
int lastState = 1;
int valueRead = 1;
int counter = 0;
int limit = 84;
int timeout = 0;
int results = new int[limit];
int pinState = new int[limit];
//set pin low for 18ms to request data
Gpio.pinMode(pin, Gpio.OUTPUT);
Gpio.digitalWrite(pin, Gpio.LOW);
Gpio.delay(18);
//get ready to recieve data back from dht11
Gpio.pinMode(pin, Gpio.INPUT);
Gpio.pullUpDnControl(pin, Gpio.PUD_UP); //activate internal pullup
while (x < limit) //84 sample changes to cover DHT11
{
timeout = 0;
counter = 2; //offset for time taken to perform read by pi
while (valueRead == lastState && timeout < 300){
Gpio.delayMicroseconds(1);
valueRead = Gpio.digitalRead(pin);
counter++;
timeout++;
}
if (timeout < 300)
{
results[x] = counter;
pinState[x] = lastState;
lastState = valueRead;
}
x++;
}
//reset our bytes
dht11_dat[0] = dht11_dat[1] =dht11_dat[2]=dht11_dat[3]=dht11_dat[4]=0;
int pointer = 0;
for (int i = 4; i<x; i=i+2){
//shift left so we are ready for next result
pointer = ((i-4) / 2) / 8;
dht11_dat[pointer] = dht11_dat[pointer] <<= 1;
//if more than 30, mark bit as 1
if (results[i] > 30){
dht11_dat[pointer] = dht11_dat[pointer] |= 1;
}
//for debugging only
// System.out.println(Integer.toString(pinState[i]) + "," + Integer.toString(results[i]));
}
int checksumByte = ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xff);
if (dht11_dat[4] != checksumByte){
System.out.println("Warning: Bad checksum value!");
}
System.out.println(" Temp: " + Integer.toString((dht11_dat[2])) + " RH: " + Integer.toString((dht11_dat[0])));
WriteToFile.writeTextToFile("RH-T.csv", Integer.toString((dht11_dat[0])) + "," + Integer.toString((dht11_dat[2])));
}
the run method:
@Override
public void run() {
ReadTempRH dht = new ReadTempRH();
while (NbSerialApp.runThreads){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(ReadTempRH.class.getName()).log(Level.SEVERE, null, ex);
}
//getTempRH(7);
scopeSensor(7);
}
}
ReadTempRH constructor:
private final int dht11_dat = {0,0,0,0,0};
public ReadTempRH() {
//setup wiringPi
if (Gpio.wiringPiSetup() == -1){
System.out.println("GPIO setup failed!");
return;
}
GpioUtil.export(3, GpioUtil.DIRECTION_OUT);
System.out.println("GPIO setup complete!");
}
Sorry my code is a little messy, I haven't had time to tidy things up! But you should get the idea. I am normally a c# guy and Netbeans doesn't work like VS in the tidying up front!
I found that the RPi3b loaded with Raspian was too slow to use the code examples shown here already. Probably something to do with a java>pi4j>wiringpi propagation delay. My approach was as follows; after sending the command to activate the sensor, I read and time level changes on the required pin and save the values into an array. Then the parsing is done later. I get a 95% success rate with this code. I have it running in a Runnable class with a loop, so it has its own thread. If you find your timings are not quite right, try adjusting the counter offset. Also enable the println marked for debugging, it helps indicate which bits were not received (indicated by a 0).
public void scopeSensor(int pin){
int x = 0;
int lastState = 1;
int valueRead = 1;
int counter = 0;
int limit = 84;
int timeout = 0;
int results = new int[limit];
int pinState = new int[limit];
//set pin low for 18ms to request data
Gpio.pinMode(pin, Gpio.OUTPUT);
Gpio.digitalWrite(pin, Gpio.LOW);
Gpio.delay(18);
//get ready to recieve data back from dht11
Gpio.pinMode(pin, Gpio.INPUT);
Gpio.pullUpDnControl(pin, Gpio.PUD_UP); //activate internal pullup
while (x < limit) //84 sample changes to cover DHT11
{
timeout = 0;
counter = 2; //offset for time taken to perform read by pi
while (valueRead == lastState && timeout < 300){
Gpio.delayMicroseconds(1);
valueRead = Gpio.digitalRead(pin);
counter++;
timeout++;
}
if (timeout < 300)
{
results[x] = counter;
pinState[x] = lastState;
lastState = valueRead;
}
x++;
}
//reset our bytes
dht11_dat[0] = dht11_dat[1] =dht11_dat[2]=dht11_dat[3]=dht11_dat[4]=0;
int pointer = 0;
for (int i = 4; i<x; i=i+2){
//shift left so we are ready for next result
pointer = ((i-4) / 2) / 8;
dht11_dat[pointer] = dht11_dat[pointer] <<= 1;
//if more than 30, mark bit as 1
if (results[i] > 30){
dht11_dat[pointer] = dht11_dat[pointer] |= 1;
}
//for debugging only
// System.out.println(Integer.toString(pinState[i]) + "," + Integer.toString(results[i]));
}
int checksumByte = ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xff);
if (dht11_dat[4] != checksumByte){
System.out.println("Warning: Bad checksum value!");
}
System.out.println(" Temp: " + Integer.toString((dht11_dat[2])) + " RH: " + Integer.toString((dht11_dat[0])));
WriteToFile.writeTextToFile("RH-T.csv", Integer.toString((dht11_dat[0])) + "," + Integer.toString((dht11_dat[2])));
}
the run method:
@Override
public void run() {
ReadTempRH dht = new ReadTempRH();
while (NbSerialApp.runThreads){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(ReadTempRH.class.getName()).log(Level.SEVERE, null, ex);
}
//getTempRH(7);
scopeSensor(7);
}
}
ReadTempRH constructor:
private final int dht11_dat = {0,0,0,0,0};
public ReadTempRH() {
//setup wiringPi
if (Gpio.wiringPiSetup() == -1){
System.out.println("GPIO setup failed!");
return;
}
GpioUtil.export(3, GpioUtil.DIRECTION_OUT);
System.out.println("GPIO setup complete!");
}
Sorry my code is a little messy, I haven't had time to tidy things up! But you should get the idea. I am normally a c# guy and Netbeans doesn't work like VS in the tidying up front!
answered Nov 11 at 2:04
Bobby Bridgeman
312
312
add a comment |
add a comment |
protected by Community♦ Dec 21 '16 at 23:12
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?