PR 記事には広告が含まれています
スポンサーリンク
Translate

家の電力逼迫状況が家のどこでも確認できるようになりました

スポンサーリンク

前回は家全体の消費電流が測定できるようになりました。今回は測定結果を別の場所でも確認できるようにしたいと思います。

スポンサーリンク

UDPマルチキャストを使う

マルチキャストはネットワークに参加している複数の端末へ、同じデータを送信する方法です。送信者はマルチキャスト用のIPアドレス(正確にはIPアドレスのうち特定の番号をマルチキャスト用に利用している)へデータを送信すると、同じIPアドレス宛のデータが欲しい受信者へ、ルーターがデータを転送してくれます。

このため、送信者は複数の端末へそれぞれデータを送信する必要がなくなり、1回送信するだけで済みます。また受信したい端末のIPアドレスを保持する必要もありません。

送信者は受信者がいるいないに関わらず勝手に送信し、受信者は勝手にデータがやってくるという、とてもシンプルな仕組みです。

スポンサーリンク

プログラム

送信側

define...
//UDP
#include <AsyncUDP.h> 
AsyncUDP udp;
const IPAddress MulticastIP = IPAddress(239, 29, 01, 41);
const uint16_t MulticastPort = 0141;
#define PacketLength 6
const uint8_t PacketHeader = 0x55;
void setup()
{
setup...
}

void loop()
{
 getData...
 sendUDP(gridI * 10, solarI * 10);
}

//UDP Multicast
void sendUDP(float i1, float i2)
{
 uint8_t message[PacketLength];
 message[0] = PacketHeader;
 int16_t temp = (int16_t)(i1);
 message[1] = (uint8_t)(temp >> 8);
 message[2] = (uint8_t)(temp & 0x00FF);

 temp = (int16_t)(i2);
 message[3] = (uint8_t)(temp >> 8);
 message[4] = (uint8_t)(temp & 0x00FF);

 uint8_t checksum = 0;
 for (int i = 1; i < PacketLength - 1 ; i++)
 {
  checksum += message[i];
 }
 message[PacketLength - 1] = checksum;

 udp.writeTo(message, PacketLength, MulticastIP, MulticastPort, TCPIP_ADAPTER_IF_STA);
}

マルチキャスト用のIPアドレスは、224.0.0.0〜239.255.255.255の範囲となっています。

5行目でIPアドレスを指定しています。239.29(ニク).01(オイ).41(シイ)を、測定した電流をマルチキャストするIPにします。

IPの他にポート番号も指定します。0141(オイシイ)をポート番号にしました。

これらのIPとポートに対してUDPを送信すれば、それでマルチキャストができてしまいます。

40行目のudp.writeTo(...)がそれです。

パケットデータはuint8_t型です。float型を直接送信するこができないので、0.1の位まで送信できるよう、測定値を10倍して整数の上位8bitと下位8bitに分けて、uint8_tの配列に入れています。

またUDPは正しいデータが届く保証がないため、パケットの先頭に0x55を、パケットの最後にチェックサムを追加して、受信側でデータが正しいのかチェックできるようにしています。

受信側

define...
//UDP
#include <AsyncUDP.h>
AsyncUDP udp;
const IPAddress MulticastIP = IPAddress(239, 29, 01, 41);
const uint16_t AmmeterMulticastPort = 0141;
#define AmmeterPacketLength 6

void setup()
{
 setup...
 //UDP recieve
 if (udp.listenMulticast(MulticastIP, AmmeterMulticastPort)) 
  {
  udp.onPacket(recvCB);
  }
}

void loop()
{
 show recieved data...
}

//UDP recieve process
void recvCB(AsyncUDPPacket& packet)
{
 //Err check
 if ( packet.length() != AmmeterPacketLength )
 {
  Serial.printf("Packet length %d is wrong.", packet.length());
  return;
 }

 uint8_t packetData[AmmeterPacketLength];
 memcpy(packetData, packet.data(), AmmeterPacketLength);
 if ( packetData[0] != PacketHeader )
 {
  Serial.printf("Packet header %x is wrong.", packetData[0]);
  return;
 }

 uint8_t checkSum = 0;
 for ( int i = 1 ; i < AmmeterPacketLength - 1 ; i++)
 {
  checkSum += packetData[i];
 }
 if ( packetData[AmmeterPacketLength - 1] != checkSum)
 {
  Serial.printf("checksum %d is wrong. calculated%d", packetData[AmmeterPacketLength - 1], checkSum);
  return;
 }

 //decode
 uint16_t temp;
 temp = ((uint16_t)packetData[1]) << 8 | (uint16_t)packetData[2];
 int16_t temp2;
 temp2 = (int16_t)temp;
 gridI = (float)temp2;
 gridI *= 0.1;
 Serial.printf("%.1f ", gridI);

 temp = ((uint16_t)packetData[3]) << 8 | (uint16_t)packetData[4];
 temp2 = (int16_t)temp;
 solarI = (float)temp2;
 solarI *= 0.1;
 Serial.printf("%.1f ", solarI);
 Serial.printf("\n");
}

13行目で、マルチキャストIP:239.29(ニク).01(オイ).41(シイ)のポート番号0141(オイシイ)を受信したいと要求します。

要求が通ると、14行目で、受信した場合に呼び出す関数(コールバック関数)を設定します。今回はパケットを受信するとrecvCB()という関数が実行されます。

recvCB関数の中では、パケットの長さ、パケットのヘッダ、チェックサムが全て正しかった場合に、パケットからデータを復元しています。

パケットのデータはuint8_tの配列になっているので、int16_tに上位と下位のデータを入れて16bitの整数にします。送信時に値を10倍にしているので、1/10してからfloatに代入します。これで、送信データが復元できました。

実行

マルチキャスト送信のプログラムを電流計のプログラムに追加しました。また別のM5StickCを用意して、マルチキャストデータを受信するプログラムを書き込みます。

送信受信ともに、液晶画面にデータを表示するプログラムは同じにしてあります。そのため、右側の送信側のM5StickCの画面のクローンが、左側の手に持っている受信用のM5StickCの画面に表示されます。

UDPのマルチキャストで、電流計のデータが他の端末に送信できるようになりました。

スポンサーリンク

電子レンジに設置

電子レンジを使った途端、ブレーカーが落ちるということはよくあることです。そのため、電子レンジに受信用M5StickCを貼り付けました。

受信側のM5StickCは、無線LANに接続されている限り、ブレーカーを流れている電流を表示してくれます。現在の値は25Aです。

電子レンジを使うと42Aまで上昇しました!うちのブレーカーは40Aなので、限界を超えてしまいました。

現在の消費電流が分かっていれば、電子レンジを使う前にどこかのエアコンを切ったりして、ブレーカーが落ちることを回避することが可能になります。

ちなみに40Aのブレーカーは「40Aになったら切れる」のではなく、「40Aは必ず通す」と設計されています。そのため、40Aでも切れません。40A以上の場合は、ある時間継続すると切れます。そのため、少し超えたくらいではブレーカーは切れません。

スポンサーリンク

どこでも消費電流がわかるよ

現在の消費電流が家のどこでも確認できるようになりました。これで、家庭内の電力の逼迫状況をリアルタイムに知ることができるようになりました。

さて次回は、この家で一番電力を逼迫させてブレーカーが落ちる原因を作っている、ある機器にこの装置を導入して問題を解決したいと思います。

この記事で使っている測定回路は、このキットを改造して使っています。