Skip to content

Commit c5a9730

Browse files
committed
Add GroveMP3V3
1 parent 2cee356 commit c5a9730

File tree

5 files changed

+253
-0
lines changed

5 files changed

+253
-0
lines changed

examples/GroveMP3V3/GroveMP3V3.ino

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// BOARD Seeed Wio LTE M1/NB1(BG96)
2+
// GROVE UART <-> Grove - MP3 V3 -Music Player (SKU#107020069)
3+
4+
#include <GroveDriverPack.h>
5+
6+
#define VOLUME (2)
7+
8+
WioCellular Wio;
9+
10+
GroveBoard Board;
11+
GroveMP3V3 MP3(&Board.UART);
12+
13+
void setup() {
14+
delay(200);
15+
SerialUSB.begin(115200);
16+
17+
Wio.Init();
18+
Wio.PowerSupplyGrove(true);
19+
20+
Board.UART.Enable(9600, 8, HalUART::PARITY_NONE, 1);
21+
if (!MP3.Init())
22+
{
23+
SerialUSB.println("Grove-MP3V3 not found.");
24+
return;
25+
}
26+
27+
int n = MP3.QueryNumberOfMusic();
28+
SerialUSB.print("Number of music = ");
29+
SerialUSB.println(n);
30+
31+
MP3.SetVolume(VOLUME);
32+
33+
for (int i = 0; i < n; ++i)
34+
{
35+
SerialUSB.print("Play ");
36+
SerialUSB.println(i);
37+
38+
MP3.Play(i);
39+
while (MP3.QueryStatus() == GroveMP3V3::STATUS_PLAY) delay(100);
40+
}
41+
}
42+
43+
void loop() {
44+
}

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ Grove
5555
|<img src="https://statics3.seeedstudio.com/seeed/img/2017-02/lJ51OXkwCFgmT6iAjE030rSd.jpg" width="100">|GroveBuzzer|107020000|[Grove - Buzzer](http://wiki.seeedstudio.com/Grove-Buzzer/)||
5656
|<img src="https://statics3.seeedstudio.com/images/product/High%20Temperature%20Sensor.jpg" width="100">|GroveHighTemp|111020002|[Grove - High Temperature Sensor](http://wiki.seeedstudio.com/Grove-High_Temperature_Sensor/)||
5757
|<img src="https://statics3.seeedstudio.com/seeed/img/2016-11/txvkIZ9IGno10T8UYi8KTvPS.jpg" width="100">|GroveGPS|113020003|[Grove - GPS](http://wiki.seeedstudio.com/Grove-GPS/)||
58+
|<img src="https://files.seeedstudio.com/wiki/Grove-MP3-V3/img/Grove-MP3-V3-preview.jpg" width="100">|GroveMP3V3|107020069|[Grove - MP3 V3 -Music Player](http://wiki.seeedstudio.com/Grove-MP3-v3/)||
5859

5960
### 拡張基板
6061

src/GroveDriverPack.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "Module/OmronBaro2SMPB02E.h"
4242
#include "Module/GroveTempHumiSHT35.h"
4343
#include "Module/Grove6AxisAccelGyroLSM6DS3.h"
44+
#include "Module/GroveMP3V3.h"
4445

4546
#if defined ARDUINO_ARCH_STM32F4 || defined ARDUINO_ARCH_STM32
4647

src/Module/GroveMP3V3.cpp

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
#include "GroveMP3V3.h"
2+
3+
static constexpr uint8_t CMD_ROOT_INDEX_PLAY_SD = 0xa2;
4+
static constexpr uint8_t CMD_STOP = 0xab;
5+
static constexpr uint8_t CMD_VOLUME_CONTROL = 0xae;
6+
static constexpr uint8_t CMD_QUERY_CURRENT_VOLUME_SETTING = 0xc1;
7+
static constexpr uint8_t CMD_QUERY_CURRENT_OPERATION_STATE = 0xc2;
8+
static constexpr uint8_t CMD_QUERY_TOTAL_NUMBER_OF_MUSIC_SD = 0xc5;
9+
10+
void GroveMP3V3::WriteCommand(uint8_t commandCode, const uint8_t* parameter, int parameterSize)
11+
{
12+
uint8_t length = 1 + 1 + parameterSize + 1;
13+
uint8_t sum = 0;
14+
sum += length;
15+
sum += commandCode;
16+
for (int i = 0; i < parameterSize; ++i) sum += parameter[i];
17+
18+
_UART->Write(0x7e);
19+
_UART->Write(length);
20+
_UART->Write(commandCode);
21+
for (int i = 0; i < parameterSize; ++i) _UART->Write(parameter[i]);
22+
_UART->Write(sum);
23+
_UART->Write(0xef);
24+
}
25+
26+
bool GroveMP3V3::ReadReturn(uint8_t* operationCode, uint8_t* returnValue, uint8_t returnValueSize, int timeout)
27+
{
28+
29+
int elapsed = 0;
30+
while (_UART->ReadAvailable() < 1)
31+
{
32+
if (elapsed * 10 >= timeout) return false;
33+
HalSystem::DelayMs(10);
34+
++elapsed;
35+
}
36+
*operationCode = _UART->Read();
37+
38+
for (int i = 0; i < returnValueSize; ++i)
39+
{
40+
elapsed = 0;
41+
while (_UART->ReadAvailable() < 1)
42+
{
43+
if (elapsed * 10 >= timeout) return false;
44+
HalSystem::DelayMs(10);
45+
++elapsed;
46+
}
47+
returnValue[i] = _UART->Read();
48+
}
49+
50+
return true;
51+
}
52+
53+
bool GroveMP3V3::Init()
54+
{
55+
int retry = 0;
56+
while (true)
57+
{
58+
GroveMP3V3::WriteCommand(CMD_QUERY_TOTAL_NUMBER_OF_MUSIC_SD, nullptr, 0);
59+
60+
uint8_t operationCode;
61+
uint8_t totalNumberOfFiles[2];
62+
if (GroveMP3V3::ReadReturn(&operationCode, totalNumberOfFiles, sizeof(totalNumberOfFiles), 100)) // timeout = 100[msec.]
63+
{
64+
if (operationCode == CMD_QUERY_TOTAL_NUMBER_OF_MUSIC_SD) break;
65+
}
66+
67+
if (retry >= 100) return false; // retry * timeout = 100 * 100 = 10[sec.]
68+
++retry;
69+
}
70+
71+
_IsExist = true;
72+
return true;
73+
}
74+
75+
void GroveMP3V3::Play(int index)
76+
{
77+
if (!_IsExist) return;
78+
79+
++index;
80+
81+
const uint8_t parameter[]{ static_cast<uint8_t>(index / 256), static_cast<uint8_t>(index % 256) };
82+
GroveMP3V3::WriteCommand(CMD_ROOT_INDEX_PLAY_SD, parameter, sizeof(parameter));
83+
84+
uint8_t operationCode;
85+
if (!GroveMP3V3::ReadReturn(&operationCode, nullptr, 0)) HalSystem::Abort();
86+
if (operationCode != 0x00) HalSystem::Abort();
87+
}
88+
89+
void GroveMP3V3::Stop()
90+
{
91+
if (!_IsExist) return;
92+
93+
GroveMP3V3::WriteCommand(CMD_STOP, nullptr, 0);
94+
95+
uint8_t operationCode;
96+
if (!GroveMP3V3::ReadReturn(&operationCode, nullptr, 0)) HalSystem::Abort();
97+
if (operationCode != 0x00) HalSystem::Abort();
98+
}
99+
100+
void GroveMP3V3::SetVolume(int volume)
101+
{
102+
if (!_IsExist) return;
103+
104+
if (volume < 0) volume = 0;
105+
if (31 < volume) volume = 31;
106+
107+
const uint8_t parameter[]{ static_cast<uint8_t>(volume) };
108+
GroveMP3V3::WriteCommand(CMD_VOLUME_CONTROL, parameter, sizeof(parameter));
109+
110+
uint8_t operationCode;
111+
if (!GroveMP3V3::ReadReturn(&operationCode, nullptr, 0)) HalSystem::Abort();
112+
if (operationCode != 0x00) HalSystem::Abort();
113+
}
114+
115+
int GroveMP3V3::QueryVolume()
116+
{
117+
if (!_IsExist) return 0;
118+
119+
GroveMP3V3::WriteCommand(CMD_QUERY_CURRENT_VOLUME_SETTING, nullptr, 0);
120+
121+
uint8_t operationCode;
122+
uint8_t currentVolume;
123+
if (!GroveMP3V3::ReadReturn(&operationCode, &currentVolume, 1)) HalSystem::Abort();
124+
if (operationCode != CMD_QUERY_CURRENT_VOLUME_SETTING) HalSystem::Abort();
125+
126+
return currentVolume;
127+
}
128+
129+
GroveMP3V3::STATUS GroveMP3V3::QueryStatus()
130+
{
131+
if (!_IsExist) return STATUS_STOP;
132+
133+
GroveMP3V3::WriteCommand(CMD_QUERY_CURRENT_OPERATION_STATE, nullptr, 0);
134+
135+
uint8_t operationCode;
136+
uint8_t currentOperationState;
137+
if (!GroveMP3V3::ReadReturn(&operationCode, &currentOperationState, 1)) HalSystem::Abort();
138+
if (operationCode != CMD_QUERY_CURRENT_OPERATION_STATE) HalSystem::Abort();
139+
140+
switch (currentOperationState)
141+
{
142+
case 1:
143+
return STATUS_PLAY;
144+
case 2:
145+
return STATUS_STOP;
146+
case 3:
147+
return STATUS_PAUSE;
148+
default:
149+
HalSystem::Abort();
150+
}
151+
152+
return STATUS_STOP; // Dummy
153+
}
154+
155+
int GroveMP3V3::QueryNumberOfMusic()
156+
{
157+
if (!_IsExist) return 0;
158+
159+
GroveMP3V3::WriteCommand(CMD_QUERY_TOTAL_NUMBER_OF_MUSIC_SD, nullptr, 0);
160+
161+
uint8_t operationCode;
162+
uint8_t totalNumberOfFiles[2];
163+
if (!GroveMP3V3::ReadReturn(&operationCode, totalNumberOfFiles, sizeof(totalNumberOfFiles))) HalSystem::Abort();
164+
if (operationCode != CMD_QUERY_TOTAL_NUMBER_OF_MUSIC_SD) HalSystem::Abort();
165+
166+
return totalNumberOfFiles[0] * 256 + totalNumberOfFiles[1];
167+
}

src/Module/GroveMP3V3.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//GROVE_NAME "Grove - MP3 V3 -Music Player"
2+
//SKU 107020069
3+
//WIKI_URL http://wiki.seeedstudio.com/Grove-MP3-v3/
4+
5+
#pragma once
6+
7+
#include "Abstract/GroveModule2.h"
8+
#include "../Connector/GroveConnectorUART.h"
9+
10+
class GroveMP3V3 : public GroveModule2
11+
{
12+
public:
13+
enum STATUS
14+
{
15+
STATUS_PLAY,
16+
STATUS_STOP,
17+
STATUS_PAUSE,
18+
};
19+
20+
private:
21+
HalUART* _UART;
22+
23+
void WriteCommand(uint8_t commandCode, const uint8_t* parameter, int parameterSize);
24+
bool ReadReturn(uint8_t* operationCode, uint8_t* returnValue, uint8_t returnValueSize, int timeout = 1000);
25+
26+
public:
27+
GroveMP3V3(GroveConnectorUART* connector)
28+
{
29+
_UART = &connector->UART;
30+
}
31+
32+
bool Init();
33+
void Play(int index); // index=1-
34+
void Stop();
35+
void SetVolume(int volume); // volume=0-31
36+
int QueryVolume(); // 0-31
37+
STATUS QueryStatus();
38+
int QueryNumberOfMusic();
39+
40+
};

0 commit comments

Comments
 (0)