tutorial raspberry pinout desde controlar java raspberry-pi sensor pi4j

java - raspberry - lea la temperatura de DHT11, usando pi4j



raspberry pi java gpio (5)

El excelente código de Eric Smith funciona bien para mí con dos pequeñas modificaciones: Primero edité esta línea:

if (counter > 16)

A:

if (counter > 30)

De acuerdo con las especificaciones de dht11 , el bit "1" se transmite cuando el retraso de "Gpio.HIGH" es aproximadamente 70us, y se transmite "0" bit si el retraso es de 26-28us. Está claro que Java tarda un poco en ejecutarse, por lo que es seguro suponer que si la demora es mayor a 30us, los datos deben ser "1". Pero esto podría tener un valor diferente si el tiempo de ejecución del programa Java es diferente en su máquina (tal vez el procesador de pi es más rápido / más lento, hay más programas en segundo plano, etc.). Por lo tanto, el 30 no es necesariamente el valor correcto para cada situación.

De acuerdo con la especificación 1 , también se puede observar que el emisor (Raspberry pi, llamado MCU en las especificaciones), también debe enviar Gpio.HIGH durante al menos 18 ms. Después de eso, la MCU debería enviarnos 20-40 us "Gpio.HIGH". Probé con System.nanoTime () el tiempo que le toma a Java ejecutar ejecutando la configuración de Gpio.Pinmode en la "Entrada". Tomó algo así como 20us, así que agregué:

Gpio.delayMicroseconds(7);

... solo para asegurarse de que el Pin esté ALTO por lo menos 20us para que el Sensor pueda registrar esa señal y comenzar a enviar sus datos de temperatura y humedad. Después de estos cambios, los datos de temperatura se leen casi siempre correctamente, la tasa de éxito es algo así como 90%. No estoy seguro de que las modificaciones funcionen con otro sistema, pero espero que este tipo de modificaciones pueda hacer que otros experimentos sean más exitosos.

(ps también hice el bucle eterno para que la clase se cree cada vez que se llama al método una y otra vez).

Intento leer los datos de temperatura de un sensor de temperatura DHT11, usando pi4j. Seguí el código escrito en c y python en este sitio: http://www.uugear.com/portfolio/dht11-h ... o-module / Pero no está funcionando. cuando pruebo la instrucción ''dht11Pin.getState ()'' siempre está en ALTO estado, nunca cambia. ¿Hay algo mal en mi código?

A continuación está mi código:

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)); }

}


Empecé con el código java del póster original y reemplacé las referencias del paquete com.pi4j.io.gpio con el paquete com.pi4j.wiringpi. Recientemente instalé el paquete pi4j más nuevo y la versión de wiringpi en mi Raspberry Pi.

Usando ese paquete, el siguiente código Java funciona aproximadamente igual que la versión c de este programa. Recibo aproximadamente del 80% al 85% de respuestas precisas con un DHT-11. Que es casi lo mismo que estaba usando WiringPi en 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!!"); } }


Obtuve una solución con Java Native Interface JNI y WiringPi.

Estoy usando java openjdk 7 en la frambuesa pi. Esto es importante para admitir las capacidades JNI de la JVM. Conecté el sensor DHT11 a GPIO1 o pin 1.

Desde el paquete raíz en src / main / java, puede instalar la biblioteca. Preparé un script en el que puedes ejecutar con el comando:

sudo sh jniDHT11SensorReaderBuilder.sh

Luego, para probar si funciona, intente ejecutar la clase DHT11SensorReader con el comando

sudo java org.mandfer.dht11.DHT11SensorReader

Si todo está bien y quiere más valores cada 1,5 segundos intente ejecutar el ejercicio 20 desde la carpeta raíz del proyecto.

sh runPi.sh org.mandfer.sunfunpi4j.Ex20_DHT11_Native

Si tienes algún problema, déjame un comentario.

Espero que ayude. Marc Andreu,


Si siempre obtiene un estado alto, podría ser bueno verificar dos veces si el cableado es correcto (o si alguno de los cables está roto, pruébelo con un led).

He usado el tutorial de adafruit en C y python y funcionó en mi DHT22.


Tengo el mismo problema y, desafortunadamente, he leído que Java no puede leer datos de DHT11 / 22 de esta manera por problemas de tiempo.

He encontrado en el foro de frambuesa un hilo en el que puedes encontrar algunas soluciones usando SPI o pigpio. Otra solución completa de Java está allí .

Recibí mi sensor ayer y todavía no he probado estas soluciones. Cuando lo intente, se lo haré saber.

[EDITAR]

Hola, resolví el problema llamando a un script de Python (que usa el controlador de Adafruit ) y leyendo su salida. El script de Python es simplemente el ejemplo publicado en la biblioteca de Adafruit. Solo cambié la salida en la línea 48 en

print ''{0:0.1f} {1:0.1f}''.format(temperature, humidity)

El método de Java que actualiza los valores con nuevos valores es:

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); } }

Para que funcione, debes instalar la biblioteca de Adafruit como se describe en la página vinculada y cambiar DHTReader.py por la ruta del scipt. Estoy trabajando para construir una "biblioteca". Si lo necesita, cuando haya terminado, lo publicaré en GitHub.