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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

mbed

mbed(エンベッド)は、Webサイト上でC++を使って開発を行う、ワンボードマイコンのプロトタイピングツールです。PCに開発環境をインストールする必要がなく、Webにアクセスできればどこにいても開発を行うことができます。

Q&A

解決済

3回答

6737閲覧

mbedでMP3モジュールへシリアル通信

Kazumori102

総合スコア45

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

mbed

mbed(エンベッド)は、Webサイト上でC++を使って開発を行う、ワンボードマイコンのプロトタイピングツールです。PCに開発環境をインストールする必要がなく、Webにアクセスできればどこにいても開発を行うことができます。

0グッド

2クリップ

投稿2017/07/01 07:44

編集2020/10/30 10:30

###前提・実現したいこと
mbedでGrove MP3モジュール v2へシリアル通信をして、
mp3を再生したいと思ってプログラミングをしているのですが、どのように信号を送ればいいのかわかりません。
そのモジュールに使われているMP3チップはKT403Aという名前で、
マニュアルや、個人のサイトを見てみましたが、わかりませんでした。

「7E FF 06 0F 00 63 FF EF」と送るとSDカード内の「255(適当な名前)」というファイル名の音声ファイルが再生されるようなのですが…

c++

1#include "mbed.h" 2 3Serial mp3(USBTX, USBRX); 4int main() { 5 mp3.baud(9600); 6 mp3.printf("ここに数字か何かを入れるのだろうけども、書式がわからない"); 7}

###補足

  1. シリアル通信の書式についていろいろ調べてみましたが、全て文字の送り方でした…
  2. モジュール自体はArduino用のようですが、秋月の店員さん曰く使えるそうです。ケーブルの配線はちゃんとしました。

###更新 17/07/03
コードはμvisionで書いており、通信にはTera Termを使っています

以下のコードで行ってみましたが音声が再生されず、~と出てきます。なぜでしょうか。検索してもわかりませんでした。検索の方法が悪かったのかもしれませんが…

なお、以下のコードは、コマンド0F(フォルダーとトラック番号を指定して再生)で、01フォルダの01ファイルを再生しようとしています。

c++

1#include "mbed.h" 2#include "stdint.h" 3Serial mp3(P1_7, P1_6);//P1_7はtx,P1_6rxです。 4int main() { 5 int idx; 6 mp3.baud(9600); 7 uint8_t send_data[] = {0x7E, 0xFF, 0x06, 0x0f, 0x00, 0x01, 0x01, 0xEF}; 8 for(idx = 0; idx < sizeof(send_data); idx++) { 9 mp3.putc(send_data[idx]); 10 } 11 12}

###更新 17/07/03 20:59
配線はTX同士、RX同士でつないでます。もしやそこがダメだったのでしょうか。
同じ名前同士でつないでおけばいいかなと思ってました。
雄と雌的な接続の考え方の方だったならばつなぎ替えます。こんな間違いをやらかすぐらいには初心者です。

マイコンは仕様的にピン接続?につないでいるときはUSB側とは不通になるそうなのですけども…詳しくは知りません。

###更新 17/07/03 22:03
TXをRXにRXをTXに接続しました。前回よりノイズが減ったように感じられますが、相変わらず~と出てきます。

###更新 17/07/10 15:43
nullbot氏の提言を試すため教授にmbed互換基盤の仕様を聞いたところ、
「シリアルで送るとPCにもモジュールにも信号が行く」とのことなのでモジュールはどうやら信号を受信できているようです。しかしそうなるとどうして再生されないのか…

###更新 17/07/18 00:42
ozwk氏の案

MP3モジュールのTxはどこにも結線せず

MP3モジュールのRxはmbedのTxに結線

を試してみましたが変化はありませんでした。
あと、

MP3モジュールのリセットをmbedの適当なGPIOに接続し、

mbedのプログラムでMP3モジュールにコマンド送る前にMP3モジュールのリセットかけて
適当な時間待ってからコマンド送信するように変更

の方はモジュールのリセット部分がどこか掴めず試せずにいます。

モジュールの生存確認を友人氏のmbedを借りて行いました。両方とも同じコードで同じ反応。
これは生か死か。

再生デバイスの選択コマンドも使ってみましたが音沙汰なし。

c++

1#include "mbed.h" 2#include "stdint.h" 3Serial mp3(P1_7, P1_6); 4int main() { 5 int idx; 6 mp3.baud(9600); 7 uint8_t set_device[] = {0x7E, 0xFF, 0x06, 0x09, 0x00, 0x00, 0x02, 0xEF};//準備 8 uint8_t set_music[] = {0x7E, 0xFF, 0x06, 0x0f, 0x00, 0x01, 0x01, 0xEF};//再生 9 wait(1); 10 for(idx = 0; idx <sizeof(set_device); idx++) { 11 mp3.putc(set_device[idx]); 12 } 13 wait(1); 14 for(idx = 0; idx <sizeof(set_music); idx++) { 15 mp3.putc(set_music[idx]); 16 } 17 18}

###17/07/18 補足
MP3のサンプリングレートが対応ということはないと思います。

・ファイルシステム:FAT16/FAT32

・オーディオフォーマット:MP3、WAV、WMA
・SDカード最大対応容量:32GB
・サンプルレート(KHz):8/11.025/12/16/22.05/24/32/44.1/48

これだけの幅ならまず外れないと思いますし...

mbed←→MP3モジュール のケーブルをもう一度点検しましたが、やはり間違っていません。過去の間違い(TXRX)は修正済みです。

###17/08/04 追記
MP3モジュールへのシリアル通信ですけども実はこれ大学のロボット製作チャレンジで音声を流したく質問した物なのです。しかしそれの期限がもう過ぎてしまったのでこれはあきらめて音声再生無しで実装しました。

期限までに実装できずに終わってしまったのですが、この質問はどうしておけばいいでしょうかね?
後日頑張って解決するまで取っておくか、それとも…

なお、ozwkさんの助言

電源5Vにしてみるとか
ソフトウェアシリアルのライブラリ使ってMP3モジュールと通信するとか

は後日試行の予定です。

###17/08/04 追記2
電圧足りてないぞこれ。今の今まで気付かなんだ。もしや…このせいでは。
要5.0VDC
出3.3VDC
別電源から引っ張ってくるか...?
ほかの出力端子3.3VDCと直列につないで6.6VDCにして抵抗噛まして5VDCにするって邪道ですかね

###17/09/18 終焉
皆様お久しぶりです。マシンが手元にある環境に戻ってまいりましたので、さっそくモジュールの電源の5V化を行いました。
無事鳴りました。

mbed本体とつなぐケーブルの電源部を切り、別途用意した5V電源(単3エネループx4直列)につないで、
「更新 17/07/03」のコードを実行したところ、何事もなかったように鳴りました。

助言をいただいた皆様本当にありがとうございました。今度からはしっかりと抜かりなく仕様書を読みます。

20/10/29 追記

ラズパイ経由で改めてこのモジュールを使用しようと思ったので、古くなったリンクの更新とともに参考サイト追加
http://www.ne.jp/asahi/shared/o-family/ElecRoom/AVRMCOM/MP3module/MP3module.html

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2017/07/03 06:52

「通信にはTera Termを使っています」どこと?いつ?何のために?
ozwk

2017/07/03 07:08

P1_7, P1_6はT/RXじゃないです。ひょっとしてKT403A側のピン番号書いてます?
Kazumori102

2017/07/03 07:23

自分の環境のmbed(の互換機)のピン番号がそうなのです。 書き込む際にTera Termを使っています
ozwk

2017/07/03 07:24

その互換機の名称を教えてください。
ozwk

2017/07/03 07:43 編集

Teratermに「~」と出るんですよね?ということはP1_7/6はPCにつながっているはずです。じゃあKT403Aはどこにつながっているんですか?また、TX同士、RX同士を繋いだりしてませんよね?
ozwk

2017/07/03 23:32

「マイコンは仕様的にピン接続?につないでいるときはUSB側とは不通になるそう」←どこに書いてあります?
ozwk

2017/07/03 23:41 編集

前回よりノイズが減ったということですが、そもそもノイズの話は今まで出てこなかったんですが、何のノイズですか?
Kazumori102

2017/07/04 13:01

接触不良系のノイズと思われます…詳しくは不明。
ozwk

2017/07/04 14:11

音声出力の話ですか?
Kazumori102

2017/07/04 15:04

そうですね。再生待機中?の音です
ozwk

2017/07/04 23:43

nullbotさんの回答(追記)は試しましたか?
Kazumori102

2017/07/05 03:20

現在試行中です。いかようにすればnullbotさんの言っていたことができるのか検証しています
ozwk

2017/07/10 07:11

とりあえずTeratermに~が出るのはその接続だと特に不思議ではないです。mbedが送信している{0x7E,...}の0x7EはAsciiコードで~ですので。
yumetodo

2017/09/22 18:18

解決お疲れ様です、が、そういうことは回答欄に書き込んで解決済みにしたほうがいいです、はたから見て解決しているかわからないので
guest

回答3

0

Serialクラスでどうやってバイナリデータを送るかってことですよね。
ドキュメント日本語
ドキュメント英語

日本語と英語で内容が全く違う・・・。

serial.putc()を使ってください。serial.writeも使えそうですが、比較的新しいAPIのようで、デバイスによってはサポートされないとのコメントを見かけました。

C++

1uint8_t send_data[] = {0x7E,0xFF,0x06,0x0F,0x00,0x63,0xFF,0xEF}; 2 3int idx; 4for(idx = 0; idx < sizeof(send_data); idx++) { 5 mp3.putc(send_data[idx]); 6} 7 8 9

##2017/7/3 追記

回路図をみるとLPC1114の47番ピン(PIO1_7)はLPC1114側から見てTXD, 46番ピン(PIO1_6)はLPC1114側から見てRXDです。
Grove UARTは1番ピンがGroveモジュール側からみてRX, 2番ピンがGroveモジュール側からみてTXです。

問題はLPC1114にはUART用のコネクタが出ていますが、謎のUSBシリアル変換ICとwired orになっていることです。
UARTはバス接続は出来ないので基本的に一対一で接続する必要がありますが、この基板ではジャンパなどで切り離せるような設計にはなっておらず、USBシリアルICを物理的に切り離すことができません。よってUARTポートが2つある基板に買い換えるのが良いかと思います。(無理にパターンカットすると書き込めなくなってしまいますし。)

もしかしたらUARTシリアルのICにTX,RXをハイインピーダンスにする機能があり回路的に切り離せるのかもしれませんが、ICの型番すらわからないためなんとも言えません。

もう一つ可能性があるとすれば入力ポートは一般的にハイインピーダンスなのでUSBシリアル変換のICのRXとGrove MP3モジュールのRXだけはwired orでもいけるかもしれません。(LPC1114側から一方的にデータを送りつけるだけなら大丈夫かもしれない)

投稿2017/07/01 14:40

編集2017/07/03 11:40
nullbot

総合スコア910

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kazumori102

2017/07/01 14:48

素早く詳細な回答をしていただきありがとうございました。 これなら私でもわかりそうです。 念のために確認ですがfor文の中身は「データ送り終わるまで繰り返すよ」ってことですよね?
yumetodo

2017/07/01 14:51

>serial.putc()を使ってください それだとフラッシュ処理が重いかなと思ったんですがそういう場合は仕方ないですね。
yumetodo

2017/07/01 14:53

>データ送り終わるまで繰り返すよ なんか違うな、「配列内のバイナリデータをすべて送る」が適切な表現だろうか
nullbot

2017/07/01 15:16

> 念のために確認ですがfor文の中身は「データ送り終わるまで繰り返すよ」ってことですよね? はい。uint8_tを使うにはstdint.hをインクルードしてやってください。もしくはunsigned charにしてもらっても大丈夫です。 > それだとフラッシュ処理が重いかなと思ったんですがそういう場合は仕方ないですね。 確かにライブラリ内で送信割り込みを使ってバッファ処理してるかわかりません。ボーレートも遅いですし気になるといえば気になりますが、頻繁に送るわけでもなさそうですし、まぁいいかと・・・。
ozwk

2017/07/03 23:36

データシートが置いてあるので UART<->USB変換は多分FT231Xっぽいですね
nullbot

2017/07/04 01:17

> ozwkさん ドキュメントありがとうございます。 > Kazumori102さん FT231XのドキュメントのP23にreset時はUARTのIOはトライステートだと書かれているのでFT231XのRESETピンをlowにしてやれば回路的に切り離すことができ、LPC1114とGroveモジュールが一対一で接続できます。 ただし回路図上はFT231Xはresetピンに#RESETというラベルだけ貼られていてLPC1114やスイッチなどに接続されていないように見えます。なのでは結局1対1で接続するに基板の改造が必要です。
Kazumori102

2017/09/23 00:13

解決しました。ご協力ありがとうございました
guest

0

MP3モジュールのTxはどこにも結線せず
MP3モジュールのRxはmbedのTxに結線

これでもダメなら
MP3モジュールのリセットをmbedの適当なGPIOに接続し、
mbedのプログラムでMP3モジュールにコマンド送る前にMP3モジュールのリセットかけて
適当な時間待ってからコマンド送信するように変更してみてください。

初期のころのT/RXの結線間違いや
UART変換モジュールのTxとMP3モジュールのTxを決戦したことで
端子ショートして死んだ可能性もあるので、
本当はシリアル2つ持ってるマイコンボードかなんかで
MP3モジュールの生存確認から始めたほうがいいんですが。

あとT/RXの結線間違いからして
他をちゃんと接続できているかも怪しいですし。


上で色々書きましたが、

「7E FF 06 0F 00 63 FF EF」と送るとSDカード内の「255(適当な名前)」というファイル名の音声ファイルが再生されるようなのですが…

とありますがデータシート読む限りこれはフォルダ63のファイル255の再生です。
フォルダ63あります?

あと再生デバイスの選択コマンドも存在して、
デフォルトがSDカードかどうか不明なので
そこら辺ちゃんと設定した方がいいと思います。

投稿2017/07/10 07:20

編集2017/07/10 07:54
ozwk

総合スコア13512

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kazumori102

2017/07/10 15:01

>MP3モジュールの生存確認 同級生のmbedで行ってみますね。 >フォルダ63あります? 更新 17/07/03の方のプログラムで試行してますので01フォルダの01ファイルを再生しようとしています。 >デフォルトがSDカードかどうか不明 確かにそうですね。
ozwk

2017/07/17 23:52

MP3のサンプリングレートが対応外とか モジュールの電源配線間違えてるとか
ozwk

2017/07/18 02:56 編集

電源5Vにしてみるとか ソフトウェアシリアルのライブラリ使って MP3モジュールと通信するとか
ozwk

2017/08/04 07:47

> ほかの出力端子3.3VDCと直列につないで6.6VDCにして抵抗噛まして5VDCにするって邪道ですかね 邪道も何も、 > 3.3VDCと直列につないで どうやって? > 抵抗噛まして5VDC 無理です。分圧点から電流を引き出す時点で電圧変わってしまいます。
Kazumori102

2017/09/23 00:13

解決しました。ご協力ありがとうございました
guest

0

ベストアンサー

Arduinoですが、公式Wikiによれば叩くためのライブラリとして

があります。これはArduinoのSoftwareSerial::write(),SoftwareSerial::available(),SoftwareSerial::read()のみで実装されています。

mbedでこれに相当するのはStream::write(),Serial::readable(),Stream::read()かと思います(StreamSerialのbase class)。ただしStream::write()SoftwareSerial::write()とちがい長さを指定できるので、MP3Player_KT403A.cppの実装のように何度もwrite()を呼び出す必要はないでしょう。

つまり上述ライブラリをパクればいいと思います。Stream::write()には上記ライブラリで渡していたバイナリ列をそっくりそのまま含むstd::uint8_t型配列を指定すればいいと思います。

・・・まあここまで書いて何ですが、私は組み込み開発って一回もやったこと無いんですけどね。でもArduinoとmbedの実装読む限りではそうだと思います。

ref:

追記

うーん、本当に書き換えはほぼCの範囲なんだけどなぁ・・・

cpp

1void SpecifyfolderPlay(uint8_t folder, uint8_t index) 2{ 3 mp3.write(0x7E); 4 mp3.write(0xFF); 5 mp3.write(0x06); 6 mp3.write(0x0F); 7 mp3.write(uint8_t(0x00)); 8 mp3.write(uint8_t(folder)); 9 mp3.write(uint8_t(index)); 10 mp3.write(0xEF); 11 delay(10); 12// return true; 13}

例えばこんな関数がありますが、

cpp

1#include "mbed.h" 2#include <cstdint> 3 4template <class T, size_t N> 5constexpr size_t size(const T (&)[N]) noexcept { return N; } 6 7using uint8_t = std::uint8_t; 8 9void SpecifyfolderPlay(uint8_t folder, uint8_t index) 10{ 11 const uint8_t out[] = { 0x7E, 0xFF, 0x06, 0x00, folder, index, 0xEF }; 12 mp3.write(reinterpret_cast<const char*>(out), size(out)); 13 wait_ms(10); 14}

こんな感じになるんじゃないですかね~、あくまでイメージですが。

投稿2017/07/01 12:53

編集2017/07/01 14:31
yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kazumori102

2017/07/01 14:18

素早く詳細な回答をしていただきありがとうございました。 実は私はまだCしか習っていないのでちょっとC++の書き方はちんぷんかんぷんなのです。もしよろしかったら紹介していただいた関数の使い方をコメントアウトで詳細を説明しつつコードを書いていただいたりできませんでしょうか?お手数掛けます。
yumetodo

2017/07/01 14:22 編集

C++そのものについての質問であればTwitter: @yumetodoに投げていただければ回答しますが、上記ライブラリの置き換えと言うのはほとんどCの範疇ですのでこれくらいできないで組み込み開発とか言われてもちょっと・・・となります。
Kazumori102

2017/09/23 00:13

解決しました。ご協力ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問