티스토리 뷰

OS/NanoPi

NanoPi M1 Plus - DHT11 control with pi4j

파란크리스마스 2017. 4. 2. 09:57
728x90

NanoPi M1 Plus - DHT11 control with pi4j

출처 : Java Native Interface (JNI) - Java Programming Tutorial
Use arrays (JNI) - Real's Java How-to - Rgagnon
android - How to return an array from JNI to Java? - Stack Overflow

NanoPi M1 Plus에서 pi4j로만으로 DHT11센서의 값을 읽을 수 없어 pi4j의 native 코드를 추가해서 온도 값을 가지고 오도록 수정하였습니다. 첨부한 jar을 적용해서 사용하세요.

pi4j-core.jar

핀배열

 DHT11  BCM  GPIO  Name  Pin
 VCC      3.3v  1
 GND  0v  9
 Sensor  3  22  CTS2  15

dht11.h

int* read_dht11_dat(int pin);

dht11.c

/*
 *  dht11.c:
 *      Simple test program to test the wiringPi functions
 *      DHT11 test
 */
  
#include <wiringPi.h>
  
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <dht11.h>

#define MAXTIMINGS      85
#define DHTPIN    3
int dht11_dat[5] = { 0, 0, 0, 0, 0 };
  
int* read_dht11_dat(int pin) {
    uint8_t laststate       = HIGH;
    uint8_t counter  = 0;
    uint8_t j          = 0, i;
    float   f; /* fahrenheit */
  
    dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
  
    /* pull pin down for 18 milliseconds */
    pinMode( pin, OUTPUT );
    digitalWrite( pin, LOW );
    delay( 18 );
    /* then pull it up for 40 microseconds */
    digitalWrite( pin, HIGH );
    delayMicroseconds( 40 );
    /* prepare to read the pin */
    pinMode( pin, INPUT );
  
    /* detect change and read data */
    for ( i = 0; i < MAXTIMINGS; i++ ) {
        counter = 0;
        while ( digitalRead( pin ) == laststate ) {
            counter++;
            delayMicroseconds( 1 );
            if ( counter == 255 ) {
                break;
            }
        }
        laststate = digitalRead( pin );
  
        if ( counter == 255 )
            break;

// printf("i = %d, j = %d\n", i, j);
  
        /* 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
     * print it out if data is good
     */
    if ( (j >= 40) && (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) ) {
        f = dht11_dat[2] * 9. / 5. + 32;
        //printf( "Humidity = %d.%d %% Temperature = %d.%d *C (%.1f *F)\n",
        //    dht11_dat[0], dht11_dat[1], dht11_dat[2], dht11_dat[3], f );
    } else {
        //printf( "Data not good, skip\n" );
    }
    
    return dht11_dat;    
}

com_pi4j_wiringpi_Gpio.h 내용 추가

/*
 * Class:     com_pi4j_wiringpi_Gpio
 * Method:    readDHT11Data
 * Signature: (II)V
 */
JNIEXPORT jintArray JNICALL Java_com_pi4j_wiringpi_Gpio_readDHT11Data
  (JNIEnv *, jclass, jint);

com_pi4j_wiringpi_Gpio.c 내용 추가

#include <dht11.h>

/*
 * Class:     com_pi4j_wiringpi_Gpio
 * Method:    readDHT11Data
 * Signature: (II)V
 */
JNIEXPORT jintArray JNICALL Java_com_pi4j_wiringpi_Gpio_readDHT11Data
  (JNIEnv *env, jclass obj, jint pin)
{
    // return (jintArray) read_dht11_dat(pin);
    int size = 5;
    jintArray result;
    result = (*env)->NewIntArray(env, size);
    if (result == NULL) {
    	return NULL; /* out of memory error thrown */
    }
    
    int *a1 = read_dht11_dat(pin);
    
    int i;
    // fill a temp structure to use to populate the java int array
    jint fill[size];
    for (i = 0; i < size; i++) {
    	 fill[i] = a1[i]; // put whatever logic you want to populate the values here.
    }
    // move from the temp structure to the java structure
    (*env)->SetIntArrayRegion(env, result, 0, size, fill);
    return result;
}

Gpio 클래스 함수 추가

package com.pi4j.wiringpi;

public class Gpio {
    
    public static native int[] readDHT11Data(int pin);
}

DHT11_native.java

import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.NanoPiM1PlusGpioProvider;
import com.pi4j.wiringpi.Gpio;
 
public class DHT11_native {
    private static final int MAXTIMINGS = 85;
    private int[] dht11_dat = { 0, 0, 0, 0, 0 };
    
    private final static int DHTPIN = 3; // 3;
 
    public float getTemperature() {
    	float f = 0;
    	dht11_dat = Gpio.readDHT11Data(DHTPIN);
    	
       if ( (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) ) {
      	 f = (float) (dht11_dat[2] * 9. / 5. + 32);
         System.out.println(String.format( "Humidity = %d.%d %% Temperature = %d.%d *C (%.1f *F)" , dht11_dat[0], dht11_dat[1], dht11_dat[2], dht11_dat[3], f) );
     } else {
    	 System.out.println( "Data not good, skip" );
     }
       
        return f;
 
    }
 
    private boolean checkParity() {
      return (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF));
    }
 
    public static void main (String ars[]) throws Exception {
    	
    	GpioFactory.setDefaultProvider(new NanoPiM1PlusGpioProvider());
 
    	DHT11_native dht = new DHT11_native();
 
        for (int i=0; i<10; i++) {
           Thread.sleep(1000);
           dht.getTemperature();
        }
 
        System.out.println("Done!!");
 
    }
}

실행

# java -cp .:pi4j-core.jar DHT11_native
Data not good, skip
Humidity = 31.0 % Temperature = 23.0 *C (73.4 *F)
Humidity = 30.0 % Temperature = 23.0 *C (73.4 *F)
Humidity = 30.0 % Temperature = 23.0 *C (73.4 *F)

실행결과

댓글
300x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 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
글 보관함