単純にデータを送信するのと受信するののみを実装してみた。
本来ならUDPなのでパケットロスや受信時は別スレッドでキューに渡してやるとかで実装するべきだが、わかりやすくするためにその辺は省いている。
※arduinoIDEを使う場合は必ずc++ファイルにすること。cとcppファイルで扱いが異なるため。platformioは知らん
simpleUDP.hpp
#ifndef _H_simpleUDP_
#define _H_simpleUDP_
//WIFI関係
#include "WiFi.h"
#include <WiFiUdp.h>
void initUDP();
void openUDP();
void SendUDP(char *str);
void RecvUDP(unsigned long timeout);
#endif
simpleUDP.cpp
#include "simpleUDP.hpp"
#include <Arduino.h>
#include "myUtilJson.h"
#include "FS.h"
#include "SD.h"
#define WIFISETTINGFILE "/wifi_setting.json" //WIFI関係の設定ファイル
// IPAddress ip(192, 168, 1, 30); //送信元IPアドレス(固定IPアドレス)
// IPAddress gateway(192,168, 1, 1); //ゲートウェイアドレス
// IPAddress subnet(255, 255, 255, 0); //サブネットマスク
// IPAddress cl01_ip(192, 168, 1, 70); //送信先IPアドレス
WiFiUDP UDP; //UDP
//wifiの初期化
void initWiFi(const char * path)
{
IPAddress ip; //送信元IPアドレス(固定IPアドレス)
IPAddress gateway; //ゲートウェイアドレス
IPAddress subnet; //サブネットマスク
MyUtilJson utiljson; //json操作クラス
DynamicJsonDocument doc(1000);
utiljson.readJson(SD,path,doc); //送信コマンドjsonファイル読み込み
const char* clip=doc["cliant"]["ip"]; //送信元IPアドレス
const char* clsubnet=doc["cliant"]["subnet"]; //サブネットマスク
const char* clgateway=doc["cliant"]["gateway"]; //ゲートウェイアドレス
const char* wifi_ssid=doc["wifi"]["ssid"]; //wifi接続先
const char* wifi_password=doc["wifi"]["password"]; //wifi接続先パスワード
if(strcmp("no",doc["cliant"]["dhcp"]) == 0)
{
//固定IPアドレスの場合
ip.fromString(clip);
gateway.fromString(clsubnet);
subnet.fromString(clgateway);
}else
{
//DHCP使用時
Serial.println("dhcp+++++++++++++++++");
//未実装
}
WiFi.mode(WIFI_STA); //無線モード(ルーターを介するやつ)
WiFi.config(ip, gateway, subnet); //IP等の設定
WiFi.begin(wifi_ssid, wifi_password); //無線の初期化
}
//UDP初期化
void initUDP()
{
initWiFi(WIFISETTINGFILE);
//initWiFi("/display_setting.json");
// Serial.println(WiFi.localIP());
}
//UDP接続
void openUDP()
{
//ルーターへの接続
while (WiFi.status() != WL_CONNECTED)
{
Serial.println("...Connecting to WiFi");
delay(1000);
}
MyUtilJson utiljson; //json操作クラス
DynamicJsonDocument doc(1000);
utiljson.readJson(SD,WIFISETTINGFILE,doc); //送信コマンドjsonファイル読み込み
// const int clport=(int)doc["cliant"]["port"]; //送信元IPアドレス
//UDP.begin(Org_Port); //UDP通信の開始
UDP.begin((int)doc["cliant"]["port"]); //UDP通信の開始
}
//UDP送信
void SendUDP(char *str)
{
IPAddress server_ip(192, 168, 1, 70); //送信先IPアドレス
MyUtilJson utiljson; //json操作クラス
DynamicJsonDocument doc(1000);
utiljson.readJson(SD,WIFISETTINGFILE,doc); //送信コマンドjsonファイル読み込み
const char* svip=doc["server"]["ip"]; //サーバIP
// const int svport=doc["server"]["port"]; //サーバポート番号
server_ip.fromString(svip);
UDP.beginPacket(server_ip, (int)doc["server"]["port"]); //パケットの開始
UDP.print(str); //送信データ書き込み
UDP.endPacket(); //パケットの終了
}
//UDP受信
void RecvUDP(unsigned long timeout)
{
char rv_data[50]; //受信バッファ
int datasize = 0; //受信データサイズ
unsigned long timestart,timenow = timestart = millis(); //経過時間用
while( (timenow - timestart) < timeout){
datasize = UDP.parsePacket();
if (datasize > 0) //受信バイト数
{
UDP.read(rv_data , datasize); //UDPデータの取得
rv_data[datasize] = '\0';
Serial.print("Recieve : ");
Serial.println(rv_data);
UDP.flush();
break;
}
timenow = millis();
}
}
json操作はarduinojsonライブラリを使用してます。ライブラリはインストールしておくこと
MyUtilJson.h
#ifndef _H_my_util_json_
#define _H_my_util_json_
#include <Arduino.h>
#include "FS.h"
#include<ArduinoJson.h>
//クラスの定義
class MyUtilJson
{
public:
void readJson(fs::FS &fs, const char* path,JsonDocument &doc);
private:
// void readFile(fs::FS &fs, const char * path,char *buf);
};
#endif
MyUtilJson.cpp
#include "myUtilJson.h"
//Jsonファイルの読み込み
void MyUtilJson::readJson(fs::FS &fs,const char *path,JsonDocument &doc)
{
/*
static char json_buf[1000];
readFile(fs, path,json_buf); //jsonファイル読み込み
Serial.println(path);
Serial.print(json_buf);
*/
File file = fs.open(path); //jsonファイルオープン
//json解析
// DeserializationError error = deserializeJson(doc, json_buf); //文字列からデシリアライズ
DeserializationError error = deserializeJson(doc, file); //ファイル(Stream)からデシリアライズ
file.close();
}
//ファイル読み込み
/*
void MyUtilJson::readFile(fs::FS &fs, const char * path,char *buf){
File file = fs.open(path);
if(!file || file.isDirectory()){
Serial.println("- failed to open file for reading");
return;
}
//ファイルの中見をコピー
int i=0;
while(file.available())
{
*(buf+i) = file.read();
i++;
}
*(buf+i) = '\0'; //終端文字
Serial.println(buf);
file.close();
//終端文字書き込まずに読み込みサイズを返すべきな気がする!!!!
}
*/
IPとかポートの設定などは外部ファイルからJSON形式で読み込むようにしている。
wifi_setting.json
{
"cliant": {
"dhcp": "no",
"ip": "192.168.1.30",
"subnet": "255.255.255.0",
"gateway": "192.168.1.1",
"port": 50001
},
"server": {
"ip": "192.168.1.70",
"port": 50007
},
"wifi": {
"ssid": "hogehoge",
"password": "fugafuga"
}
}