サーバ
import processing.net.*; //ネットワークライブラリの使用宣言
String RecvMsg,zouka;
float RecvData; // 受信用のfloat型変数
int state = 0; // サーバの受信状態
PImage RecvImg; //受信画像を格納するPImage型変数
int imgIndex = 0;
int cnt =0;
int state1=0;
//最大クライアント数
final int MAX_CLIENT = 2; //定数
Server[] myServer = new Server[MAX_CLIENT]; //サーバクラスの宣言
String[] ServerIP = new String[MAX_CLIENT]; //サーバIP表示用文字列
Client[] myClient = new Client[MAX_CLIENT]; //クライアントクラスの宣言
String[] ClientIP = new String[MAX_CLIENT]; //クライアントIP表示用文字列
String[] Message = new String[MAX_CLIENT]; //クライアントごとの表示メッセージ用文字列
int numClient; //接続クライアント数
//******************************************************************************
// 初期設定関数
//******************************************************************************
void setup( )
{
size( 600, 500 );
//日本語フォント(BIZ UDゴシック)で、サイズ16のフォントを生成
PFont font = createFont("BIZ UDゴシック", 16, true);
textFont(font); // 生成したフォントを設定
//サーバの起動(クライアント毎にポート番号を5554と6554にしました.適当笑)
myServer[0] = new Server(this, 5554); //クライアントA用にします.
myServer[1] = new Server(this, 6554); //クライアントB用にします.
for( int i = 0; i < MAX_CLIENT; i++ ){
ServerIP[i] = myServer[i].ip( ); // 自分のIPアドレスを文字列に記録
ClientIP[i] = " "; // クライアントIPアドレス表示用文字列の初期値
Message [i] = " "; // メッセージの初期値
}
RecvMsg = " ";
RecvData = 0.0f; // 初期値
numClient = 0; //接続クライアント数を0にリセット
}
void stop( ){
for( int i = 0 ; i < MAX_CLIENT; i++ )
myServer[i].stop( );
}
void draw( ) // 画面描画(100ms毎に勝手に繰り返す)
{
background(#086C52); // 緑に塗りつぶす.
//左上にクライアントと自分のIPアドレスを表示
for( int i = 0 ; i < MAX_CLIENT; i++ ){
//左上から下に向かって,サーバと自IPアドレスを表示
text("サーバ : " + ServerIP[i], 30, 20 + i * 100 );
text("クライアント: " + ClientIP[i], 30, 40 + i * 100 );
text(Message[i] , 30, 60 + i * 100 );
}
text( RecvMsg , 30, 60 );
text("荷物数"+cnt,70,80);
//受信文字列を表示
text("受信データ:" + nf(RecvData,1,2), 50, 100 );
// 受信画像をウィンドウに表示
if( RecvImg != null )
image(RecvImg, 45, 200, RecvImg.width * 0.6, RecvImg.height * 0.5);
}
//******************************************************************************
// クライアント接続時に起動されるイベント
//******************************************************************************
void serverEvent( Server ConServer, Client ConClient )
{
String[] ClientID = {"A", "B"}; //クライアントの名前(表示用)
//クライアントがどのポートから接続してきたかチェック
//ポートに対応するクライアントを表(配列)に登録.
for( int i = 0; i < MAX_CLIENT; i++ ){
if( ConServer == myServer[i] ){
myClient[i] = ConClient;
ClientIP[i] = ConClient.ip( );
Message [i] = "クライアント" + ClientID[i] + "と接続";
numClient++; //接続クライアント数を+1
}
}
}
/*
//*************************************************************************
//データを受信したら起動されるイベント(引数は送信先の情報)
//*************************************************************************
int ImgWidth = 0; // 受信画像の幅
int ImgHeight = 0; // 受信画像の高さ
int NumBytes = 0;
void clientEvent(Client RecvClient){
//String RecvDataString;
NumBytes = RecvClient.available( ); //受信データのバイト数を確認
if( NumBytes>=1 && NumBytes<=2 ){ //受信データがあったら
println("増加を検知s");
}
// 受信状態に応じた動作の記述(状態0:画像の高さと幅の受信, 状態1:画像データの受信)
switch(state){
//--------------------------------------------------------------------------------------------------
case 0 : // 画像の高さと幅を受信
//--------------------------------------------------------------------------------------------------
//NumBytes = RecvClient.available( ); //受信データのバイト数を確認
if( NumBytes >= 8 ){ //8バイト分、データを受信したら
byte[] TmpBuff = RecvClient.readBytes(NumBytes); //今受け取ったバイトデータを一時バッファに保存
ImgHeight = (TmpBuff[3] & 0xff) << 24 | (TmpBuff[2] & 0xff) << 16 | (TmpBuff[1] & 0xff) << 8 | TmpBuff[0] & 0xff;
ImgWidth = (TmpBuff[7] & 0xff) << 24 | (TmpBuff[6] & 0xff) << 16 | (TmpBuff[5] & 0xff) << 8 | TmpBuff[4] & 0xff;
Message[2] = "高さ= " + ImgHeight + ", 幅= " + ImgWidth;
state = 1; //状態遷移
myServer.write(1); // 高さと幅の受信完了をクライアントに通知
println("a");
}
break;
//--------------------------------------------------------------------------------------------------
case 1 : // 画像データの受信(総画素数×RGBの3バイト)
//--------------------------------------------------------------------------------------------------
if( NumBytes >= ImgHeight * ImgWidth *3 ){ //全画像データ(RGB×高さ×幅)を受信したら
Message[2] += " => 受信完了: " + NumBytes + "[バイト]";
byte[] TmpBuff = RecvClient.readBytes(NumBytes);//受信バッファ内の全画像データを読み出す。
//画像を格納するメモリ領域を確保
println(ImgWidth);
println(ImgHeight);
RecvImg = createImage(ImgWidth, ImgHeight, RGB);
int idx = 0;
for( int i = 0; i < ImgWidth * ImgHeight; i++ ){
//画素を詰め込む。
RecvImg.pixels[i] = color(( TmpBuff[idx+0] & 0xff), ( TmpBuff[idx+1] & 0xff), ( TmpBuff[idx+2] & 0xff));
idx += 3;
}
RecvImg.updatePixels( ); //領域のアップデート
String savedFileName = "Image" + imgIndex + ".jpg";
RecvImg.save(savedFileName);
Message[2] += "⇒保存" + savedFileName;
imgIndex++;
state = 0; //状態遷移
myServer.write(300); // 画像データの受信完了をクライアントに通知
println("aa");
}
break;
default : break;
}
}*/
// 画像を受け取る関数
void clientEvent(Client client) {
byte[] receivedData = client.readBytes(); // クライアントからバイトデータを受信
if (receivedData != null && receivedData.length > 10000) {
String fileName = "Received_Image_" + imgIndex + ".jpg"; // 受信画像のファイル名を生成
saveBytes(fileName, receivedData); // 受信データを保存
RecvImg = loadImage(fileName); // 保存した画像を読み込む
byte[] fileData = loadBytes(fileName); // ファイルをバイト配列として読み込む、消すかも
byte[] senddata={1,1};//長さ2
myServer[1].write(senddata);//消すかも
cnt=0;
if (RecvImg != null) {
println("画像を受信し保存しました: " + fileName);
imgIndex++;
Message[1] = "画像を受信し保存しました: " + fileName;
} else {
println("画像の読み込みに失敗しました: " + fileName);
Message[1] = "画像の読み込みに失敗しました: " + fileName;
}
}
//試し
else if (receivedData != null && receivedData.length >= 1) {
String receivedText = new String(receivedData).trim(); // バイトデータを文字列に変換して空白を削除
// 入力が数値かどうかを確認
if (isNumeric(receivedText)) {
int imageIndex = Integer.parseInt(receivedText); // 数値に変換
String fileName = "Received_Image_" + imageIndex + ".jpg"; // ファイル名を生成
println("画像を送信: " + fileName);
byte[] fileData = loadBytes(fileName); // ファイルをバイト配列として読み込む
myServer[1].write(fileData); // クライアントBに送信
} else {
println("画像データが無効です。");
Message[1] = "画像データが無効です。";
println("増加");
cnt++;
myServer[1].write(1);//荷物の増加を通知
}
}
//試し
else {
println("画像データが無効です。");
Message[1] = "画像データが無効です。";
println("増加");
cnt++;
myServer[1].write(1);
}
}
//******************************************************************************
// データ受信時に起動されるイベント
//******************************************************************************
/*void clientEvent( Client ConClient )
{
RecvMsg = "クライアント(" + ConClient.ip( ) + ")と接続";
// クライアントから画像データを受信
receiveImage(ConClient);
cnt=0;
}
}*/
boolean isNumeric(String str) {
try {
Integer.parseInt(str); // 数値変換を試みる
return true;
} catch (NumberFormatException e) {
return false; // 変換できない場合はfalseを返す
}
}
クライアントA(マイコン)
import processing.net.*; //ネットワークライブラリの使用宣言
import processing.serial.*;
import processing.video.*; // 動画ライブラリの使用宣言
import gab.opencv.*;
Serial Myport;
int numRecvByte = 0;
int [] ADIntVal = new int [2];
float [] ADRealVal = new float[2];
byte [] RecvByteBuff = new byte[256];
Client myClient; //クライアントクラスclientの宣言
float SendData; //送信するfloat型の変数
float val0 = 0;//増加検知用の変数
int state1 = 0;//状態
int state2=0;
String[] FileName = new String[4]; // 画像ファイル名を格納する文字列配列
String[] Message = new String[2]; // メッセージ用文字列
String Time;
PImage[] img = new PImage[4]; // イメージ型配列imgを宣言
Capture video; // Captureオブジェクトの宣言
OpenCV opencv;
int numImg = 0; // 送信する画像のインデックス
int state = 0;
float val1=0;
//******************************************************************************
// 初期設定関数
//******************************************************************************
void setup( ){
size( 1000, 700 ); // ウィンドウを生成
// 日本語フォント(BIZ UDゴシック)で、サイズ16のフォントを生成
PFont font = createFont("BIZ UDゴシック", 16, true);
textFont(font); // 生成したフォントを設定
// サーバーに接続(localhostは自パソコン)
myClient = new Client( this, "localhost", 5554 );
SendData = 0.0f; // 初期値
int i;
for (i = 0; i < Serial.list().length; i++){
println(Serial.list()[i]);
}
println("ARE available");
Myport = new Serial(this, Serial.list()[i-1], 115200);
// カメラの設定(デバイス番号0、解像度640x480)
video = new Capture(this, 640,480);
opencv = new OpenCV(this, 640,480);
video.start();
Message[0] = Message[1] = " "; // メッセージの初期値
}
PImage binImg;
void draw( ) //画面描画(100ms毎に起動)
{
background(#FF7F50); //オレンジに塗りつぶす.
Myport.write(0);
String[] cameras = Capture.list();
while( cameras.length == 0){
cameras = Capture.list();
}
//左上にクライアントと自分のIPアドレスを表示
text( "クライアント: " + myClient.ip(), 30, 20 );
//送信データを表示
text("電圧値 =" + nf(ADRealVal[0],1, 2) + "[V]",30,40);
Time = year() + "年" + month() + "月" + day() + "日" + hour() + ":" + minute() + ":" + second();
text(Time,10,60);
if(video != null){
set(10,130,video);
opencv.loadImage(video);
}
if(val0==0 && state2==1){
takepic();
sendimg();
state2=0;
println("aas");
}
else if(val0>0){
state2=1;
println("hhs");
}
}
void captureEvent(Capture camera){
camera.read();
}
//電圧値計算
/*String SendDataString;
int calVol(){
//String SendDataString;
RecvByteBuff[numRecvByte] = (byte) RecvPort.read();
numRecvByte++;
if(numRecvByte == 4){
ADIntVal[0] = RecvByteBuff[1] << 8 |(RecvByteBuff[0] & 0xff);
ADRealVal[0] = ((ADIntVal[0] / 1023.0) * 5.0);
numRecvByte = 0;
//float型を文字列に変換
if(ADRealVal[0] - val0 > 0.2 && state1 == 0){
//重さが増えたら
SendDataString = str(ADRealVal[0]);
val0 = ADRealVal[0];
state1 = 1;
delay(200);
return 0;
//サーバに文字列を送信
//myClient.write(SendDataString);
}
else if(ADRealVal[0] == 0.0 && state1 == 1){
val0 = 0;
SendDataString = str(ADRealVal[0]);
state1 = 0;
delay(200);
return 1;
//myClient.write(SendDataString);
}
}
return 2;
}*/
void serialEvent (Serial RecvPort){
String SendDataString;
RecvByteBuff[numRecvByte] = (byte) RecvPort.read();
numRecvByte++;
if(numRecvByte == 4){
ADIntVal[0] = RecvByteBuff[1] << 8 |(RecvByteBuff[0] & 0xff);
ADRealVal[0] = ((ADIntVal[0] / 1023.0) * 5.0);
numRecvByte = 0;
//float型を文字列に変換
if(ADRealVal[0] - val0 > 0.2){
//重さが増えたら
SendDataString = str(ADRealVal[0]);
val0 = ADRealVal[0];
state1 = 1;
myClient.write(1);
delay(400);
//サーバに文字列を送信
//myClient.write(SendDataString);
}
if(ADRealVal[0] == 0.0 && state1 == 1){
val0 = 0;
SendDataString = str(ADRealVal[0]);
state1 = 0;
delay(200);
//myClient.write(SendDataString);
}
}
}
// 写真を撮影
void takepic() {
PImage capturedFrame = video.get();
String savedFileName = "Image.jpg";
capturedFrame.save(savedFileName); // カメラのフレームを保存
// 保存した画像を読み込み配列に格納
img[numImg] = loadImage(savedFileName);
if (img[numImg] == null) {
println("画像の読み込みに失敗しました: " + savedFileName);
} else {
println("画像が正常に読み込まれました: " + savedFileName);
Message[1] = "写真を撮影し保存し、送信準備完了: " + savedFileName;
}
}
/*
//画像を送信
int ImgHeight = 0;
int ImgWidth = 0;
byte[] SendImgData;
void sendimg() {
int NumBytes = 2;
switch (state) {
case 0: // 画像の高さと幅の送信
//NumBytes = c.available();
if (NumBytes >= 1) {
//c.clear(); // 受信バッファを空にする。
// 画像の高さと幅を送信(それぞれint型4バイト)
ImgHeight = img[numImg].height;
ImgWidth = img[numImg].width;
byte[] SendHW = new byte[8]; // 送信用バッファ
// 画像の高さを送信バッファに詰める。
SendHW[0] = (byte) ImgHeight;
SendHW[1] = (byte)(ImgHeight >> 8);
SendHW[2] = (byte)(ImgHeight >> 16);
SendHW[3] = (byte)(ImgHeight >> 24);
// 画像の幅を送信バッファに詰める。
SendHW[4] = (byte) ImgWidth;
SendHW[5] = (byte)(ImgWidth >> 8);
SendHW[6] = (byte)(ImgWidth >> 16);
SendHW[7] = (byte)(ImgWidth >> 24);
myClient.write(SendHW); // バッファをサーバに送信
state = 1; // 状態遷移
println("画像のサイズを送信しました");
}
break;
case 1: // 画像データの送信
//NumBytes = c.available();
//if (NumBytes >= 1) {
// // 受信バッファを空にする。
// 送信バッファの動的確保(総画素数×RGBの3バイト分)
SendImgData = new byte[ImgWidth * ImgHeight * 3];
int idx = 0;
// 画像データを全部、送信バッファに詰め込む。
for (int i = 0; i < ImgWidth * ImgHeight; i++) {
color pix = img[numImg].pixels[i]; // 画像データから1画素を取り出す。
SendImgData[idx + 0] = (byte) red(pix); // 画素の赤成分を送信バッファに詰める。
SendImgData[idx + 1] = (byte) green(pix); // 画素の緑成分を送信バッファに詰める。
SendImgData[idx + 2] = (byte) blue(pix); // 画素の青成分を送信バッファに詰める。
idx += 3;
}
myClient.write(SendImgData); // 送信バッファをサーバに送信
//state = 0; // 状態遷移
println("画像データを送信しました");
//}
break;
case 2: // サーバーから画像データの受信完了が来るまで待つ
//NumBytes = c.available();
println(NumBytes);
if (NumBytes >= 1) {
//c.clear(); // 受信バッファを空にする。
Message[1] = FileName[numImg] + " : 画像送信の完了 " + SendImgData.length + "[バイト]";
state = 0;
}
break;
}
}
void clientEvent(Client c){
int NumBytes1=c.available();
if(NumBytes1==1){
c.clear();
state=1;
}
if(NumBytes1==2){
c.clear();
state=0;
}
}*/
// 写真を送信
void sendimg() {
if (img[numImg] != null) {
String fileName = "Image.jpg"; // 送信するファイル名
byte[] fileData = loadBytes(fileName); // ファイルをバイト配列として読み込む
if (fileData != null) {
myClient.write(fileData); // クライアントにファイルデータを送信
println("画像を送信しました: " + fileName);
Message[1] = "画像を送信しました: " + fileName;
} else {
println("画像データの読み込みに失敗しました: " + fileName);
Message[1] = "画像データの読み込みに失敗しました: " + fileName;
}
} else {
println("送信可能な画像がありません。");
Message[1] = "送信可能な画像がありません。";
}
}
クライアントB
import processing.net.*;
import java.util.ArrayList;
String[] Message = new String[3];
int state = 0; // サーバの受信状態
PImage RecvImg;
int imgIndex = 0;
String Time;
ArrayList<String> logs = new ArrayList<>(); // ログを保持するリスト
Client myClient; //クライアントクラスclientの宣言
void setup() {
size(860, 580);
PFont font = createFont("BIZ UDゴシック", 16, true);
textFont(font);
myClient = new Client(this,"localhost", 6554);
Message[0] = "サーバ:" + myClient.ip();
Message[1] = " ";
Message[2] = " ";
}
void stop() {
myClient.stop();
}
void draw() {
background(#2D3986);
fill(255);
text(Message[0] , 30, 20);
//text(Message[1], 100, 30);
text(Message[2], 30, 40);
Time = year() + "年" + month() + "月" + day() + "日" + hour() + ":" + minute() + ":" + second();
// ログを画面に表示
fill(255);
int logY = 60; // ログの表示開始位置
for (int i = 0; i < logs.size(); i++) {
text(logs.get(i), 30, logY + i * 20); // 各ログを表示
}
text(Time,200,20);
// 受信画像をウィンドウに表示
if( RecvImg != null )
image(RecvImg, 45, 200, RecvImg.width * 0.6, RecvImg.height * 0.5);
}
void serverEvent(Server s, Client c) {
Message[1] = "クライアント(" + c.ip() + ")と接続";
}
// 画像を受け取る関数
void clientEvent(Client client) {
//int NumBytes=0;
//NumBytes = client.available();
byte[] receivedData = client.readBytes(); // クライアントからバイトデータを受信
if(receivedData.length==1){
Message[2] = "荷物が届いています";
}
else if (receivedData != null && receivedData.length > 8) {
String fileName = "Received_Image_" + imgIndex + ".jpg"; // 受信画像のファイル名を生成
saveBytes(fileName, receivedData); // 受信データを保存
RecvImg = loadImage(fileName); // 保存した画像を読み込む
if (RecvImg != null) {
println("画像を受信し保存しました: " + fileName);
Message[2] = "荷物は空です";
imgIndex++;
Message[1] = year() + "年" + month() + "月" + day() + "日" + hour() + ":" + minute() + ":" + second()+"に画像を受信し保存しました: " + fileName;
addLog(Message[1]);
} else {
println("画像の読み込みに失敗しました: " + fileName);
Message[1] = "画像の読み込みに失敗しました: " + fileName;
}
} else {
println("画像データが無効です。");
Message[1] = "画像データが無効です。";
}
}
/*
int NumBytes=0;
//******************************************************************************
// データ受信時に起動されるイベント
//******************************************************************************
void clientEvent(Client ConClient ){
NumBytes = ConClient.available();
if(NumBytes>=8){
// クライアントから画像データを受信
receiveImage(ConClient);
Message[2] = "荷物は空です";
}
else{
Message[2] = "荷物が届いています";
}
}*/
void addLog(String log) {
logs.add(log); // 新しいログを追加
if (logs.size() > 20) { // 最大20件まで表示
logs.remove(0); // 最古のログを削除
}
}