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
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 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!