raspberryPiとESP32をUDP通信してみる
ルータを使ってraspberryPIとESP32をwifi接続してUDP通信をしてみます。💪
なんだか難しいそうだけど、IPアドレスはルーターから貰えるし、接続するポートを適当に選んでやれば接続できます。
イメージはこんな感じです。(IPアドレスは適当に書いてあります)
簡単に説明するとIPアドレスは、送り先の住所、ポート番号はデータを出したり受けたりするポストです。
いろいろ調べているとソケットという言葉も出来てきます。
ソケットはOSに対して、どんな通信をどのIPアドレス、どのポートを使ってやるかという宣言です。
上記の図だと、UDP_IPはraspberryPiがルーターからもらったIPアドレス(192.168.10.3)、ポート番号は自分で決めたポート(9000)になります。
まずはサーバー側のRaspberryPiのプログラムです。pythonで書いてます。
import socket
import struct
import time
from contextlib2 import closing
UDP_IP="192.168.43.41"
UDP_PORT=9000
sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
sock.bind((UDP_IP,UDP_PORT))
count =0
with closing(sock):
while True:
count +=1
data,addr = sock.recvfrom(1024)
print("Send from ESP",addr,"-",data)
time.sleep(1)
#sock.sendto(b'hello\0',addr)
mes = (str(count)+'\0').encode()
sock.sendto(mes,addr)
軽くプログラムを解説すると、まずソケットを使ってUDP通信を行うための、お呪いの3行です。😙
sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
sock.bind((UDP_IP,UDP_PORT))
参考までに
受信データがあると、下記の行で受信データと送信をしてきた相手のIPアドレスとポートを受信します。
data,addr = sock.recvfrom(1024)
データを受信した後は、送信してきたアドレスにデータ返信をしています。
送信データはencode()でバイナリー型に変換します。アドレスは先ほど受信したアドレスをそのまま使います。
mes = (str(count)+'\0').encode()
sock.sendto(mes,addr)
次にクライアントであるESP32のプログラムです。
ESP32の方はOSがないので、ソケットという考えはありません。UDP通信をするライブラリーを使います。arduinodでのプログラムです。
#include <WiFi.h>
#include <WiFiUDP.h>
const char ssid[] = "your ssid; // SSID
const char pass[] = "your password"; // password
static WiFiUDP wifiUdp;
static const char *raspberryIP = "192.168.10.3";
static const int raspberryPort = 9000; //送信先のポート
IPAddress remoteIP; // 相手のIPアドレス
int port;
static void WiFi_setup()
{
static const int kLocalPort = 7000; //自身のポート
WiFi.begin(ssid, pass);
while( WiFi.status() != WL_CONNECTED) {
delay(500);
}
wifiUdp.begin(kLocalPort);
}
static void Serial_setup()
{
Serial.begin(115200);
Serial.println(""); // to separate line
}
void setup() {
Serial_setup();
WiFi_setup();
}
void loop()
{
int count=0;
char i[64];
while(1){
count++;
//パケットの送信
wifiUdp.beginPacket(raspberryIP, raspberryPort);
wifiUdp.printf("ESP32Dev Bord: %d", count);
wifiUdp.endPacket();
//パケットの受信
if (wifiUdp.parsePacket()) {
wifiUdp.read(i,64);
remoteIP = wifiUdp.remoteIP();
port = wifiUdp.remotePort();
Serial.print(remoteIP);
Serial.print(" / ");
Serial.print(port);
Serial.print(" / ");
Serial.println(i); // UDP通信で来た値を表示
}
delay(3000);
}
}
パケットとしてRaspberryPiにデータを送信した後、返信があればデータを受信します。受信データのほか、送信してきたコンピュータのアドレスとポートも受信しています。
wifiUdp.read(i,64);
remoteIP = wifiUdp.remoteIP();
port = wifiUdp.remotePort();
実行した時のRaspberry PiとESP32の表示です。
今回は1対1で通信しましたが、UDP通信を使うとRaspberryPiをサーバーにしてESP32を複数繋ぐことができます。送信してきたアドレスとポートも分かるため、誰からのデータか、返信はどこに送れば良いかも分かります。💯
このUDP通信ですが、簡単に使えるのでスマホなどにUDP通信のアプリがたくさんあります。これらを使えばスマホでコントロールするシステムを簡単に作成することができます。😆
少し、長くなってしまいオーバーヒート気味なので今日はここまでで
では🤚