太陽光パネルを設置した時からやりたかったことが実現できたので、共有します。
使ったもの
■Tracerのチャージコントローラを使った太陽光発電システムTracer 2210RNと100wのパネル4枚を組み合わせたシステムを利用しました。
発電システムの詳細はこちら。
21万円で100Wの太陽光パネル4枚を使った24v230Ah(5420Wh)の蓄電システムを組む
■インターネットに繋がったraspberry pi
今回は4Gドングルでインターネットに接続したraspberry pi B+を使いました。
wifiやLANケーブルでのインターネット接続でも問題ありません。
今回使用したドングルの設定方法詳細はこちら。
Raspberry piでPIXELAのLTE対応USBドングルを使う方法
■チャージコントローラとRaspberry piを接続する道具
- LANケーブル
 - LANケーブルDIP化キット
 - ユニバーサル基板
 - オスメスジャンパワイヤ
 
■インターネットでログが確認できるサービス
ThingSpeekは、汎用的に使えそうなデータ収集サービスです。
物理的な接続方法
このように接続します。実際に接続すると、このようになりました。
フランス語のサイトですが、情報が整理されていたので、通信内容の参考になりました。
Contrôle de chargeur solaire
solar chargerについて議論しているraspberry piのフォーラムです。
Interfacing with Solar Charge Controller
api_keyの取得
ThingSpeekでチャンネルを作成し、write api keyを取得してください。https://thingspeak.com/
今回はこのようなチャンネル設定にしました。
api_keyはここにあります。
プログラムの設定
raspberry piの適当な場所に下記のプログラムを作成します。mkdir ~/autorun_programs/ vi ~/autorun_programs/solar_power_logger.py
httpリクエスト以外のprintはコメントアウトしていますが、内容を確認したい場合は「#」を取って動作させてみてください。
~/autorun_programs/solar_power_logger.py
import serial
import time
import requests
def hex_2byte_to_int(hex_2byte):
  return int(hex_2byte[1].encode('hex') + hex_2byte[0].encode('hex'), 16)
tracer_start_command = "\xAA\x55\xAA\x55\xAA\x55\xEB\x90\xEB\x90\xEB\x90"
tracer_id = "\x16"
tracer_kind_command = "\xA0\x00\xB1\xA7\x7F"
tracer_command_to_send = tracer_start_command + tracer_id + tracer_kind_command
port = serial.Serial("/dev/ttyAMA0", baudrate=9600, timeout=1.0)
port.open()
time.sleep(1)
port.flushInput()
port.flushOutput()
while (1):
  panel_volt_sum            = 0
  battery_charge_ampere_sum = 0
  battery_volt_sum          = 0
  # get average of 6 time in 1 min
  for i_per_10sec in range(6):
    port.write(tracer_command_to_send)
    #print 'send: ' + tracer_command_to_send.encode('hex')
    #port.flush()
    data = port.read(100)
    #print 'received: ' + data.encode('hex')
    #print ''
    #print 'syncro: '  + data[0:6].encode('hex')
    #print 'address: ' + data[6].encode('hex')
    #print 'command: ' + data[7].encode('hex')
    length = int(data[8].encode('hex'), 16)
    #print 'length: '  + data[8].encode('hex') + '(' + str(length) + ')'
    info = data[9:9+length]
    #print 'info: '  + info.encode('hex')
    #print 'crc16: ' + data[9+length:11+length].encode('hex')
    #print 'end: '   + data[11+length].encode('hex')
    #print ''
    battery_volt = hex_2byte_to_int(info[0:2])
    #print 'battery_volt: ' + str(battery_volt)
    panel_volt = hex_2byte_to_int(info[2:4])
    #print 'panel_volt: ' + str(panel_volt)
    #print 'reserved: ' + str(hex_2byte_to_int(info[4:6]))
    #out_ampere = hex_2byte_to_int(info[6:8])
    #print 'out_ampere: ' + str(out_ampere)
    #out_volt = hex_2byte_to_int(info[8:10])
    #print 'out_volt: ' + str(out_volt)
    #batt_full_volt = hex_2byte_to_int(info[10:12])
    #print 'batt_full_volt: ' + str(batt_full_volt)
    #print 'outputting?: ' + info[12].encode('hex')
    #print 'over_output?: ' + info[13].encode('hex')
    #print 'loading_to_circuit?: ' + info[14].encode('hex')
    #print 'reserved: ' + info[15].encode('hex')
    #print 'is_overloaded_battery?: ' + info[16].encode('hex')
    #print 'is_overdischarged_battery?: ' + info[17].encode('hex')
    #print 'is_full?: ' + info[18].encode('hex')
    is_charging = int(info[19].encode('hex'), 16)
    #print 'is_charging?: ' + str(is_charging)
    #print 'battery_temp: ' + str(int(info[20].encode('hex'), 16) -30)
    battery_charge_ampere = hex_2byte_to_int(info[21:23])
    #print 'charge_ampere: ' + str(battery_charge_ampere)
    #print 'reserved: ' + info[23].encode('hex')
    #print is_charging
    #print float(battery_volt) / 100
    #print float(panel_volt) / 100
    #print float(charge_ampere) / 100
    #print ''
    panel_volt_sum            += float(panel_volt)            / 100
    battery_charge_ampere_sum += float(battery_charge_ampere) / 100
    battery_volt_sum          += float(battery_volt)          / 100
    time.sleep(10)
  panel_volt_to_send            = panel_volt_sum            / 6
  battery_charge_ampere_to_send = battery_charge_ampere_sum / 6
  battery_volt_to_send          = battery_volt_sum          / 6
  # for thingspeak
  r = requests.post('https://api.thingspeak.com/update.json',
    data = {
      'field1' : panel_volt_to_send,
      'field2' : battery_charge_ampere_to_send,
      'field3' : battery_volt_to_send,
      'field4' : battery_volt_to_send * battery_charge_ampere_to_send,
      'api_key' : '[your api_key]',
    })
  print r.text
プログラム作成にあたっては、「物理的な接続方法」で紹介したリンクと、下記のプログラムを参考にしました。
Arduino向けに書かれたチャージコントローラとの通信プログラムです。
tracer/arduino/Tracer/Tracer.ino
実行
下記のコマンドで実行します。python ~/autorun_programs/solar_power_logger.py
自動起動にしたい場合は、crontabにreboot後の処理として上記のコマンドを記述します。
crontab -e
@reboot python ~/autorun_programs/solar_power_logger.py &
自動起動のもうひとつの手段としてrc.localがありますが、今回の場合この手段は使えません。
なぜなら、gpioが有効になるのはrc.localが実行された後だからです。
GPIO state after boot
データ確認
thingspeekにデータが登録されていることを確認します。自分が登録しているデータは、下記のリンクで確認できます。
https://thingspeak.com/channels/124019
iframeで埋め込むことも可能です。
<iframe width="450" height="250" src="https://api.thingspeak.com/channels/124019/charts/4" ></iframe>
iframeのurlにパラメータを指定することで、グラフの見せ方を変えられます。
詳しくはこちらのサイトをご参考ください。
Create a Chart
<iframe width="100%" height="250" src="https://api.thingspeak.com/channels/124019/charts/4?average=60&width=auto&yaxismin=0&color=%236fd16f&results=1440" ></iframe>以上です。
面白がってもらえたり、何かの参考になれば嬉しいです。
その他参考
下記のサイトの説明で、通信で取得できる電流値はバッテリーへの電流だと分かりました。
EPsolar製 コントローラーオプション
EPsolar製 コントローラーオプション







0 件のコメント :
コメントを投稿