質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
M5Stack

M5Stackは、小型のマイコンモジュールです。拡張モジュールが豊富に用意されており、センサと組み合わせることで測定機能を自由に追加することができます。

IDE

IDE、統合開発環境((Integrated Development Environment)とは、テキストエディタ以上の機能を提供して、ソフトウェア開発を効率をあげるコンピュータプログラムを指す。

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

受付中

M5Stick同士で音声通信がしたい

Letemon
Letemon

総合スコア0

M5Stack

M5Stackは、小型のマイコンモジュールです。拡張モジュールが豊富に用意されており、センサと組み合わせることで測定機能を自由に追加することができます。

IDE

IDE、統合開発環境((Integrated Development Environment)とは、テキストエディタ以上の機能を提供して、ソフトウェア開発を効率をあげるコンピュータプログラムを指す。

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0回答

0評価

1クリップ

16閲覧

投稿2020/11/10 08:17

編集2022/01/12 10:55

やりたいこと:M5StickC同士での音声通信

使用しているパーツ:M5StickC本体、SPKHAT

UDP通信で音声データを送るコードを書いているのですが、送信はおそらくできているのですが、受信ができていないみたいです。

具体的には、送信側のコードのwifi_send()関数内の
wifiUdp.beginPacket(pc_addr, pc_port);
wifiUdp.write(send_num);
wifiUdp.write(recPos_a);
wifiUdp.write(recPos_b);
wifiUdp.endPacket();
は、受信側で受け取れているのですが、2回目以降のwifiUdp.beginPacket(pc_addr, pc_port);で送る
wifiUdp.write(send_num);
wifiUdp.write(soundStorage[recPos_bef]);
が受け取ることができていません。

受信側では、wifi_receive() 関数内のint num_packet = wifiUdp.parsePacket();で受け取ったnum_packetが
Serial.printで0と表示されます。

送信側コード #include <M5StickC.h> #include <driver/i2s.h> #include <WiFi.h> #include <WiFiUDP.h> #define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \ ((x)<< 8 & 0x00FF0000UL) | \ ((x)>> 8 & 0x0000FF00UL) | \ ((x)>>24 & 0x000000FFUL) ) #define PIN_CLK (0) // I2S Clock PIN #define PIN_DATA (34) // I2S Data PIN #define SAMPLING_RATE (16384) // サンプリングレート(44100, 22050, 16384, more...) #define BUFFER_LEN (1024) // バッファサイズ //#define STORAGE_LEN (102400) // 本体保存容量(MAX 100K前後) #define STORAGE_LEN (52400) #define WAVE_EXPORT (0) // WAVEファイルに出力するか const char* ssid = "????????"; const char* password = "?????????"; WiFiUDP wifiUdp; const char *pc_addr = "??????????????"; //"???????";//相手のipアドレス(com4:192.168.11.22) const int pc_port = 50008; //送信先のポート const int my_port = 50007; //自身のポート uint8_t soundBuffer[BUFFER_LEN]; // DMA転送バッファ uint8_t soundStorage[STORAGE_LEN]; // サウンドデータ保存領域 bool recFlag = false; // 録音状態 int recPos = 0; // 録音の長さ int recPos_bef = 0; // 録音をする void i2sRecord() { // 録音用設定 i2s_config_t i2s_config = { .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM), .sample_rate = SAMPLING_RATE, .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, .channel_format = I2S_CHANNEL_FMT_ALL_RIGHT, .communication_format = I2S_COMM_FORMAT_I2S, .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, .dma_buf_count = 2, .dma_buf_len = BUFFER_LEN, .use_apll = false, .tx_desc_auto_clear = true, .fixed_mclk = 0, }; // PIN設定 i2s_pin_config_t pin_config; pin_config.bck_io_num = I2S_PIN_NO_CHANGE; pin_config.ws_io_num = PIN_CLK; pin_config.data_out_num = I2S_PIN_NO_CHANGE; pin_config.data_in_num = PIN_DATA; // 録音設定実施 i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); i2s_set_pin(I2S_NUM_0, &pin_config); i2s_set_clk(I2S_NUM_0, SAMPLING_RATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO); // 録音開始 recFlag = true; xTaskCreatePinnedToCore(i2sRecordTask, "i2sRecordTask", 2048, NULL, 1, NULL, 1); } // 録音用タスク void i2sRecordTask(void* arg) { // 初期化 recPos = 0; memset(soundStorage, 0, sizeof(soundStorage)); // 録音処理 while (recFlag) { size_t transBytes; // I2Sからデータ取得 i2s_read(I2S_NUM_0, (char*)soundBuffer, BUFFER_LEN, &transBytes, (100 / portTICK_RATE_MS)); // int16_t(12bit精度)をuint8_tに変換 recPos_bef = recPos;//どこから送信するか for (int i = 0 ; i < transBytes ; i += 2 ) { if ( recPos < STORAGE_LEN ) { int16_t* val = (int16_t*)&soundBuffer[i]; soundStorage[recPos] = ( *val + 32768 ) / 256; recPos++; } } wifi_send(); Serial.printf("transBytes = %d, STORAGE_LEN=%d, recPos=%d\n", transBytes, STORAGE_LEN, recPos); vTaskDelay(1 / portTICK_RATE_MS); } i2s_driver_uninstall(I2S_NUM_0); // タスク削除 vTaskDelete(NULL); } void wifi_send() { Serial.println("------------------Send Start------------------"); // データ送信 int send_num = 0;//何回目のsendか int recPos_a = recPos_bef/256; int recPos_b = recPos_bef%256; wifiUdp.beginPacket(pc_addr, pc_port); send_num++; wifiUdp.write(send_num); wifiUdp.write(recPos_a); wifiUdp.write(recPos_b); for(int i=0;recPos_bef<recPos;i++){ if(i%180 == 0){//180回ごとに送る wifiUdp.endPacket();//1460byte(/8=182bit)以上になると捨てられるので注意 Serial.println("Send middle"); delay(10); wifiUdp.flush(); int begPac = wifiUdp.beginPacket(pc_addr, pc_port); if(begPac == 0){ Serial.println("beginPacket miss"); }else{ Serial.println("beginPacket OK"); } send_num++; wifiUdp.write(send_num); Serial.print("send_num : "); Serial.println(send_num); } wifiUdp.write(soundStorage[recPos_bef]);//send_num=1から始まる recPos_bef++; } wifiUdp.endPacket();//1460byte(/8=182bit)以上になると捨てられるので注意 Serial.println("------------------Send End------------------"); } void setup() { M5.begin(); M5.Lcd.setRotation(3); M5.Lcd.fillScreen(WHITE); M5.Lcd.setTextColor(BLACK, WHITE); M5.Lcd.println("Sound Recorder"); M5.Lcd.println("BtnA Record"); WiFi.begin(ssid, password); while( WiFi.status() != WL_CONNECTED) { M5.Lcd.print("."); delay(500); } M5.Lcd.print("\r\nWiFi connected\r\nIP address: "); M5.Lcd.println(WiFi.localIP()); wifiUdp.begin(my_port); delay(500);//wifiUdp.begin()の処理を待つ時間 M5.Lcd.println("Setup OK"); } void loop() { M5.update(); if ( M5.BtnA.wasPressed() ) { // 録音スタート //M5.Lcd.setCursor(0, 24); M5.Lcd.println("REC..."); Serial.println("Record Start"); i2sRecord(); } else if ( M5.BtnA.wasReleased() ) { // 録音ストップ M5.Lcd.setCursor(0, 24); M5.Lcd.println(" "); recFlag = false; delay(100); // 録音終了まで待つ Serial.println("Record Stop"); } delay(10); }
受信側 #include <M5StickC.h> #include <driver/i2s.h> #include <WiFi.h> #include <WiFiUDP.h> #define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \ ((x)<< 8 & 0x00FF0000UL) | \ ((x)>> 8 & 0x0000FF00UL) | \ ((x)>>24 & 0x000000FFUL) ) #define PIN_CLK (0) // I2S Clock PIN #define PIN_DATA (34) // I2S Data PIN #define SAMPLING_RATE (16384) // サンプリングレート(44100, 22050, 16384, more...) #define BUFFER_LEN (1024) // バッファサイズ //#define STORAGE_LEN (102400) // 本体保存容量(MAX 100K前後) #define STORAGE_LEN (52400) const char* ssid = "???????????"; const char* password = "?????????"; WiFiUDP wifiUdp; const char *pc_addr = "??????????"; //"????????";//相手のipアドレス const int pc_port = 50007; //送信先のポート const int my_port = 50008; //自身のポート uint8_t receive_soundBuffer[BUFFER_LEN]; // DMA転送バッファ uint8_t receive_soundStorage[STORAGE_LEN]; // サウンドデータ保存領域 uint8_t receive_soundStorage_tmp[185]; // サウンドデータ保存領域 bool recFlag = false; // 録音状態 int recPos = 0; // 録音の長さ // 再生をする void i2sPlay(){ //省略 } void wifi_receive() { int num_packet = wifiUdp.parsePacket(); if (num_packet){ Serial.print("num_packet : "); Serial.println(num_packet); int recPos_tmp,recPos_a,recPos_b; int j = 0; int send_num;//何回目のsendか int send_num_tmp = 2;//次に受け取りたいsend_numの番号 send_num = wifiUdp.read(); recPos_a = wifiUdp.read(); recPos_b = wifiUdp.read(); recPos_tmp = recPos_a*256 + recPos_b;//1回で送られた録音の長さ recPos += recPos_tmp;//最終的な録音の長さ Serial.print("recPos_tmp : "); Serial.println(recPos_tmp); delay(5); while(1){ num_packet = wifiUdp.parsePacket(); if (num_packet){ send_num = wifiUdp.read(); Serial.print("send_num : "); Serial.println(send_num); if(send_num == send_num_tmp){ Serial.println("Receive middle"); int len = wifiUdp.read(receive_soundStorage_tmp,num_packet-1); for(int i=0;i<len;i++){ receive_soundStorage[i] = receive_soundStorage_tmp[i]; } send_num_tmp++; if(j<recPos_tmp){ j += len; }else{break;} } }else{ Serial.println("num_packet = 0"); delay(5); } } Serial.println("Receive End"); } } void setup() { M5.begin(); M5.Lcd.setRotation(3); M5.Lcd.fillScreen(WHITE); M5.Lcd.setTextColor(BLACK, WHITE); M5.Lcd.println("Sound Recorder"); M5.Lcd.println("BtnA Record"); M5.Lcd.println("BtnB Play"); WiFi.begin(ssid, password); while( WiFi.status() != WL_CONNECTED) { M5.Lcd.print("."); delay(500); } M5.Lcd.print("\r\nWiFi connected\r\nIP address: "); M5.Lcd.println(WiFi.localIP()); wifiUdp.begin(my_port); delay(500);//wifiUdp.begin()の処理を待つ時間 M5.update(); } void loop() { wifi_receive(); if ( M5.BtnB.wasReleased() ) { Serial.println("sizeof : "); Serial.println(sizeof(receive_soundStorage)); // 再生スタート M5.Lcd.setCursor(0, 24); M5.Lcd.println("Play..."); Serial.println("Play Start"); i2sPlay(); M5.Lcd.println("Play Stop"); Serial.println("Play Stop"); recPos = 0; M5.update(); } }

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

thkana
thkana

2020/11/10 23:39

まだそんなに精査していませんが、 WiFiUDP::parsePacket\(\)はブロックしないで未受信時には0を返す仕様だったと思います。 受信したとき以外は0を返すので、大量に"num_packet = 0"が表示されるのが当然と思いますが、そういうことではなくて、パケットが送信されたはずの時にも一切受信されない、ということなのですか\?
Letemon
Letemon

2020/11/11 02:45

回答頂きありがとうございます。 はい、”パケットが送信されたはずの時にも一切受信されない”状態です。 具体的には、送信側のコードのwifi_send\(\)関数内の最初のパケット(send_num,recPos_a,recPos_bの3つ)は受信できています。 しかし、その後のfor文内でパケット(send_num,soundStorage\[recPos_bef\])を送信したはずなのに一切受信されていないです。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

M5Stack

M5Stackは、小型のマイコンモジュールです。拡張モジュールが豊富に用意されており、センサと組み合わせることで測定機能を自由に追加することができます。

IDE

IDE、統合開発環境((Integrated Development Environment)とは、テキストエディタ以上の機能を提供して、ソフトウェア開発を効率をあげるコンピュータプログラムを指す。

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。