Raspberry Piでソーラー蓄電システムの遠隔監視やってみた

2020年1月31日

実家に次いで一人暮らしのアパートでもオフグリッドソーラー発電を始めました。

実家に帰った時にも状況を把握したいので、バッテリー電圧や温湿度をRaspberry Piで遠隔監視するシステムを構築することに。

使用したもの

仕様

処理の流れ

  1. Arduinoで温湿度センサーと分圧抵抗による電圧測定回路を作成し、その測定値をUSB接続でシリアルポート転送
  2. Raspbery PiでWi-Fi接続し、Webサーバーを立ちあげて、Arduinoから取得した測定値を表示。

Arduinoの内部処理

温湿度センサー DHT22/AM2302とアナログ入力値を電圧に変換したものをLCDとシリアルポートへ転送しています。

oled.ino

#include <DHT.h>
#include <DHT_U.h>

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for SSD1306 display connected using software SPI (default case):
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
  OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

const int PIN_DHT = 2;
DHT dht(PIN_DHT,DHT22);

void setup() {
  dht.begin();
  Serial.begin(9600);
  pinMode(A0,INPUT);
  if(!display.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
}

void loop() {
  display.clearDisplay();
  dht.readHumidity();
  dht.readTemperature();
  delay(125);
  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();
  double original = analogRead(A0);
  double volt = original;
  // Ankerのシガーソケット Pi Zero
  volt *= 0.0279347826086957;
  display.setTextSize(2);      // Normal 1:1 pixel scale
  display.setTextColor(WHITE); // Draw white text
  display.setCursor(0, 0);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font
  display.print(humidity);
  display.println("%");
  display.print(temperature);
  display.println("C");
  display.print(volt);
  display.println("V");
  display.print(original);
  display.display();
  if(Serial.available() > 0){
    if(Serial.read() == '1'){
      Serial.print("{\"humidity\":");
      Serial.print(humidity);
      Serial.print(",\"temperature\":");
      Serial.print(temperature);
      Serial.print(",\"volt\":");
      Serial.print(volt);
      Serial.print(",\"original\":");
      Serial.print(original);
      Serial.println("}");
    }
  }
}

Raspberry Piの内部処理

Arduinoからの値の取得にはPythonを使用しています。取得した値はファイル(sensor.json)へ保存。

/home/pi/get.py

import serial
import time
s = serial.Serial("/dev/ttyUSB0",9600,timeout=1)

while 1:
	s.write("1")
	time.sleep(0.5)
	f = open("/var/www/html/sensor.json",mode="w")
	str = s.readline()
	print str
	f.write(str)
	f.close()

Pythonの実行はcronで行っていて、OS起動時に一回だけ呼び出し、後はPython内で無限ループし続けます。

/var/spool/cron/crontabs/root

@reboot python /home/pi/get.py

Webブラウザへの表示はHTML/CSS+JQuery(JavaScript)。sensor.jsonの値をブラウザへ出力します。

/var/www/html/status.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>温湿度/バッテリー電圧監視</title>
	<style>
	* {
		border:0;
		margin:0;
	}
	#battery {
		width: 128px;
		height: 52px;
		position: relative;
	}
	#hasi {
		position: absolute;
		margin-top: 15px;
		width: 8px;
		height: 20px;
		background-color:#555555;
	}
	#border {
		position: absolute;
		border:5px solid #555555;
		width: 110px;
		left: 8px;
		height: 45px;
	}
	#battery_available {
		position:absolute;
		background-color:#00FF00;
		top:8px;
		right:8px;
		width:104px;
		height:40px;
	}
	</style>
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
	<script>
		var max = 12.8;
		var min = 12.0;
		function getStatus(){
		    $.getJSON("./sensor.json",function(data){
		        $(".temperature").text(data.temperature);
		        $(".humidity").text(data.humidity);
		        $(".volt").text(data.volt);
			if(data.volt > max){
				data.volt = max;
			}
			var available = (data.volt - min) / (max - min) * 104;
			$("#battery_available").css("width",available + "px");
		        $(".original").text(data.original);
		    });
		}
		$(function(){
			setInterval(getStatus,500);
		});
	</script>
</head>
<body>
<h1>温湿度/バッテリー電圧監視</h1>
<h2>気温:<span class="temperature"></span> ℃</h2>
<h2>湿度:<span class="humidity"></span> %</h2>
<h2>電圧:<span class="volt"></span> V</h2>
<div id="battery">
	<div id="hasi"></div>
	<div id="border"></div>
	<div id="battery_available"></div>
</div>
<h2>Original:<span class="original"></span></h2>
</body>
</html>

組み上げ

一通り配線、プログラム調整が終わり準備ができました。

LCDには温湿度とバッテリー電圧、電圧のアナログ入力値が表示されます。

チャージコントローラーのUSB出力端子に接続し電源を確保。

Raspberry PiからArduinoへ電源供給します。

電源供給とともにOSが起動します。

蓋をしてビニールシートで覆ったので動作確認。

ブラウザから動作確認

WebブラウザからRaspberry Piのアドレスを指定すると、上手く動作してくれました。

課題

動作時の消費電力は130mAh程。このシステムのバッテリーの型番は「40B19L」なので28Ahです。

充電しない状態で半分の14Ah使用を想定した場合、107時間(4.48日)となります。

雲行きの怪しい日が5日以上続くと、監視システムだけで半分以上のバッテリーを消費してしまいます。

バッテリーを増やしたり、監視システムそのものの消費電力を減らす等で対応していきたい。