【Java】Raspberry Piで室温、湿度を取得

2021年11月3日

pigpioを使った温度と湿度を取得するプログラムをJavaで書いてみたので、自分用に内容を記事にしときたいと思います。

前回の記事でDHT22を動かす為の配線を行いましたので、これを動かしていきます。

プログラムはリモートでテストしていきます。

ライブラリは私がwatchdogメソッドを修正したバージョンを使います。
https://github.com/nompor/jpigpio

元のライブラリはこれです。
https://github.com/nkolban/jpigpio

作成したプログラムは光の強さが数値で表示されるようになっています。

import java.math.BigDecimal;
import java.math.RoundingMode;

import jpigpio.GPIOListener;
import jpigpio.JPigpio;
import jpigpio.PigpioException;
import jpigpio.PigpioSocket;

public class DHT22 {

	static final int MAX_NO_RESPONSE = 2;

	PigpioSocket pi = null;
	int gpio = 17;
	double temp = 0;
	double rhum = 0;
	long bad_CS = 0;  // Bad checksum count.
	long bad_SM = 0;  // Short message count.
	long bad_MM = 0;  // Missing message count.
	long bad_SR = 0;  // Sensor reset count.
	long high_tick = 0;
	long bit = 40;
	long no_response;
	long val;
	long CS;

	long hH = 0;
	long hL = 0;
	long tH = 0;
	long tL = 0;
	long lastTick;
	public static void main(String[] args) throws InterruptedException, PigpioException {
		new DHT22().execute();
	}

	void execute() throws PigpioException, InterruptedException{
		pi = new PigpioSocket("192.168.121.122", 8888);

		pi.gpioSetPullUpDown(gpio,JPigpio.PI_PUD_UP);
		pi.setWatchdog(gpio, 0);


        GPIOListener listen = new GPIOListener(gpio,JPigpio.PI_EITHER_EDGE ) {

			@Override
			public void alert(int gpio, int level, long tick) {
				try {
					_cb(gpio,level,tick);
				} catch (PigpioException e) {
					e.printStackTrace();
				}
			}
		};

		pi.addCallback(listen);

		try {
			while (true) {
				trigger();
				System.out.println("温度:"+temperature()+" 湿度:"+humidity());
				Thread.sleep(3000);
			}
		} finally {
			pi.gpioTerminate();
		}
	}

	void _cb(int gpio, int level, long tick) throws PigpioException {

		long diff = tick - high_tick;

		double mult=0;

		if (level == 0){

			// Edge length determines if bit is 1 or 0.

			if ( diff >= 50 ){
				val = 1;
				if ( diff >= 200 ) {
					CS = 256;
				}
			} else {
				val = 0;
			}

			if ( bit >= 40 ){
				bit = 40;

			} else if ( bit >= 32 ) {
				CS	= (CS << 1) + val;

				if (bit == 39){

					pi.setWatchdog(gpio, 0);

					no_response = 0;

					long total = hH + hL + tH + tL;
					if ((total & 255) == CS){

						rhum = (double)((hH << 8) + hL) * 0.1;

						if ((tH & 128)!=0){
							mult = -0.1;
							tH = tH & 127;
						}else {
							mult = 0.1;
						}

						temp = (double)((tH << 8) + tL) * mult;

					}else {

						bad_CS += 1;
					}
				}

			}else if ( bit >= 24 ) {
				tL = (tL << 1) + val;

			}else if ( bit >= 16 ) {
				tH = (tH << 1) + val;

			}else if ( bit >= 8 ) {
				hL = (hL << 1) + val;

			}else if ( bit >= 0 ) {
				hH = (hH << 1) + val;

			}else {
			}

			bit += 1;

		}else if( level == 1 ) {
			high_tick = tick;
			if (diff > 250000){
				bit = -2;
				hH = 0;
				hL = 0;
				tH = 0;
				tL = 0;
				CS = 0;
			}

		} else{
			pi.setWatchdog(gpio, 0);

			if (bit < 8) {
				bad_MM += 1;
				no_response += 1;
				if (no_response > MAX_NO_RESPONSE){
					no_response = 0;
					bad_SR += 1;

				}


			}else if (bit < 39) {
				bad_SM += 1;
				no_response = 0;

			}else {
				no_response = 0;
			}
		}
	}
	void trigger() throws PigpioException, InterruptedException {
		pi.gpioWrite(gpio, JPigpio.PI_LOW);
		Thread.sleep(19);
		pi.gpioSetMode(gpio, JPigpio.PI_INPUT);
		pi.gpioSetPullUpDown(gpio,JPigpio.PI_PUD_UP);
		pi.setWatchdog(gpio, 200);
	}

	BigDecimal temperature() {
		return new BigDecimal(temp).setScale(1, RoundingMode.HALF_UP);
	}

	BigDecimal humidity() {
		return new BigDecimal(rhum).setScale(1, RoundingMode.HALF_UP);
	}
}
実行結果

温度:0.0 湿度:0.0
温度:21.1 湿度:50.3
温度:21.2 湿度:50.4
温度:21.1 湿度:50.8
温度:21.1 湿度:51.3
温度:21.1 湿度:50.8
温度:21.1 湿度:50.5

関連記事