application: new way on playing songs
now always plays right after the end of a song/message instead of waiting fixed times. announces the actual time instead of waiting for the 3 minutes mark. plays songs and comical messages in an endless loop. plays a message when the door is opened.
This commit is contained in:
parent
a100716cfc
commit
557c8777b1
|
@ -11,8 +11,10 @@ Next, a display has been added to show the time spent in the water room.
|
|||
This would put some pressure on the user to not spend too much time on the loo and hold up the queue.
|
||||
|
||||
Finally, it has been connected to the speakers.
|
||||
A welcome message would greed the new comer, followed by a pleasant music.
|
||||
After three minutes, a comical message would encourage the slow rider to hurry up.
|
||||
A welcome message would greed the new comer, followed by a (random) pleasant music.
|
||||
Then the time passed inside is announced, followed by a (random) comical message.
|
||||
And the loop continues with another song.
|
||||
Once you exit the place, a short (random) message is played.
|
||||
|
||||
board
|
||||
=====
|
||||
|
|
185
application.c
185
application.c
|
@ -1,4 +1,4 @@
|
|||
/** STM32F1 application example
|
||||
/** dachboden klo-assistant firmware
|
||||
* @file
|
||||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @copyright SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
@ -130,14 +130,29 @@ enum mp3_commands_t {
|
|||
MP3_CMD_QUERY_FLDR_COUNT = 0x4f,
|
||||
};
|
||||
|
||||
/** which song group we are currently playing */
|
||||
static enum playing_state_t {
|
||||
PLAYING_STATE_OFF, /**< playing any song or track */
|
||||
PLAYING_STATE_INTRO, /**< playing the welcome message */
|
||||
PLAYING_STATE_SONG, /**< playing any song */
|
||||
PLAYING_STATE_TIMER_INTRO, /**< playing the time announcement intro */
|
||||
PLAYING_STATE_TIMER_MINUTES, /**< playing the number of minutes */
|
||||
PLAYING_STATE_TIMER_MINUTE, /**< playing the minute announcement */
|
||||
PLAYING_STATE_TIMER_SECONDS, /**< playing the number of seconds */
|
||||
PLAYING_STATE_TIMER_OUTRO, /**< playing the timer announcement closing word */
|
||||
PLAYING_STATE_TALK, /**< playing any talk track */
|
||||
PLAYING_STATE_EXIT, /**< playing any exit message */
|
||||
} playing_state = PLAYING_STATE_OFF; /**< which song group we are currently playing */
|
||||
|
||||
/** RTC timestamps when the last MP3 response track finished has been received */
|
||||
static uint32_t last_finished = 0;
|
||||
|
||||
/** number of possible music tracks */
|
||||
#define MUSIC_TRACKS 19
|
||||
/** if a music track has been played */
|
||||
static bool music_played = false;
|
||||
#define MUSIC_TRACKS 24
|
||||
/** number of possible exit message tracks */
|
||||
#define EXIT_TRACKS 18
|
||||
/** number of possible talk tracks */
|
||||
#define TALK_TRACKS 27
|
||||
/** if a talk track has been played */
|
||||
static bool talk_played = false;
|
||||
|
||||
size_t putc(char c)
|
||||
{
|
||||
|
@ -193,6 +208,53 @@ static void command_reset(void* argument);
|
|||
*/
|
||||
static void command_bootloader(void* argument);
|
||||
|
||||
/** send command to MP3 playes
|
||||
* @param[in] cmd command to send
|
||||
* @param[in] data argument for command (such as track number)
|
||||
*/
|
||||
static void mp3_command(enum mp3_commands_t cmd, uint16_t data)
|
||||
{
|
||||
puts("MP3 command: ");
|
||||
switch (cmd) {
|
||||
case MP3_CMD_PLAY:
|
||||
puts("play");
|
||||
break;
|
||||
case MP3_CMD_NEXT_SONG:
|
||||
puts("next");
|
||||
break;
|
||||
case MP3_CMD_STOP_PLAY:
|
||||
puts("stop");
|
||||
break;
|
||||
case MP3_CMD_PLAY_FOLDER_FILE:
|
||||
puts("playing ");
|
||||
const uint8_t folder = data >> 8;
|
||||
const uint8_t track = data & 0xff;
|
||||
printf("%02u/%03u", folder, track);
|
||||
if (0 == folder) {
|
||||
puts(" (invalid input folder 0)");
|
||||
}
|
||||
if (0 == track) {
|
||||
puts(" (invalid input track 0");
|
||||
}
|
||||
break;
|
||||
case MP3_CMD_SET_VOLUME:
|
||||
printf("set volume to %u", data);
|
||||
break;
|
||||
case MP3_CMD_RESET:
|
||||
puts("reset");
|
||||
break;
|
||||
default:
|
||||
printf("%+02x");
|
||||
break;
|
||||
}
|
||||
putc('\n');
|
||||
|
||||
uint8_t command[] = {0x7e, 0xff, 0x06, cmd, 0x01, data >> 8, data, 0xef}; // command template (with feedback)
|
||||
for (uint8_t i = 0; i < LENGTH(command); i++) {
|
||||
usart_send_blocking(USART(MP3_UART), command[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** process response received from MP3 player
|
||||
* @return if a valid response has been received
|
||||
*/
|
||||
|
@ -251,6 +313,55 @@ static bool mp3_response(void)
|
|||
break;
|
||||
case 0x3d:
|
||||
puts("track finished");
|
||||
if ((rtc_get_counter_val() - last_finished) < 2) {
|
||||
const uint16_t time_passed = (rtc_get_counter_val() - timer_door_closed) / RTC_TICKS_SECOND; // how many seconds have passed since door has been closed
|
||||
switch (playing_state) {
|
||||
case PLAYING_STATE_INTRO: // the welcome message finished
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (2 << 8) + (rtc_get_counter_val() % MUSIC_TRACKS) + 1); // play random music track
|
||||
playing_state = PLAYING_STATE_SONG; // remember we are playong a song (for the first time)
|
||||
break;
|
||||
case PLAYING_STATE_SONG: // the song finished
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (5 << 8) + 65); // play time announcement
|
||||
playing_state = PLAYING_STATE_TIMER_INTRO; // remember we are playing the timer announcement
|
||||
break;
|
||||
case PLAYING_STATE_TIMER_INTRO: // the time intro finished
|
||||
if (0 == (time_passed / 60)) {
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (5 << 8) + 60); // play number of minutes announcement
|
||||
} else {
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (5 << 8) + (time_passed / 60)); // play number of minutes announcement
|
||||
}
|
||||
playing_state = PLAYING_STATE_TIMER_MINUTES; // remember we are playing the number of minutes
|
||||
break;
|
||||
case PLAYING_STATE_TIMER_MINUTES: // the minutes announcement finished
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (5 << 8) + 62); // play minute announcement
|
||||
playing_state = PLAYING_STATE_TIMER_MINUTE; // remember we are playing the minute announcement
|
||||
break;
|
||||
case PLAYING_STATE_TIMER_MINUTE: // the minute announcement finished
|
||||
if (0 == (time_passed % 60)) {
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (5 << 8) + 60); // play number of seconds announcement
|
||||
} else {
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (5 << 8) + (time_passed % 60)); // play number of seconds announcement
|
||||
}
|
||||
playing_state = PLAYING_STATE_TIMER_SECONDS; // remember we are playing the number of seconds
|
||||
break;
|
||||
case PLAYING_STATE_TIMER_SECONDS: // the number of seconds finished
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (5 << 8) + 64); // play time outro announcement
|
||||
playing_state = PLAYING_STATE_TIMER_OUTRO; // remember we are playing the timer outro announcement
|
||||
break;
|
||||
case PLAYING_STATE_TIMER_OUTRO: // the timer outro announcement finished
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (3 << 8) + (rtc_get_counter_val() % TALK_TRACKS) + 1); // play random talk track
|
||||
playing_state = PLAYING_STATE_TALK; // remember we are playing the talk track
|
||||
break;
|
||||
case PLAYING_STATE_TALK: // the talk track finished
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (2 << 8) + (rtc_get_counter_val() % MUSIC_TRACKS) + 1); // play random music track
|
||||
playing_state = PLAYING_STATE_SONG; // remember we are playing a song (again)
|
||||
break;
|
||||
default:
|
||||
playing_state = PLAYING_STATE_OFF; // we won't play anything else
|
||||
break;
|
||||
}
|
||||
}
|
||||
last_finished = rtc_get_counter_val(); // remember last time we received the ack
|
||||
break;
|
||||
case 0x40:
|
||||
puts("error");
|
||||
|
@ -269,52 +380,6 @@ static bool mp3_response(void)
|
|||
mp3_rx_len = 0; // reset message
|
||||
return true;
|
||||
}
|
||||
/** send command to MP3 playes
|
||||
* @param[in] cmd command to send
|
||||
* @param[in] data argument for command (such as track number)
|
||||
*/
|
||||
static void mp3_command(enum mp3_commands_t cmd, uint16_t data)
|
||||
{
|
||||
puts("MP3 command: ");
|
||||
switch (cmd) {
|
||||
case MP3_CMD_PLAY:
|
||||
puts("play");
|
||||
break;
|
||||
case MP3_CMD_NEXT_SONG:
|
||||
puts("next");
|
||||
break;
|
||||
case MP3_CMD_STOP_PLAY:
|
||||
puts("stop");
|
||||
break;
|
||||
case MP3_CMD_PLAY_FOLDER_FILE:
|
||||
puts("playing ");
|
||||
const uint8_t folder = data >> 8;
|
||||
const uint8_t track = data & 0xff;
|
||||
printf("%02u/%03u", folder, track);
|
||||
if (0 == folder) {
|
||||
puts(" (invalid input folder 0)");
|
||||
}
|
||||
if (0 == track) {
|
||||
puts(" (invalid input track 0");
|
||||
}
|
||||
break;
|
||||
case MP3_CMD_SET_VOLUME:
|
||||
printf("set volume to %u", data);
|
||||
break;
|
||||
case MP3_CMD_RESET:
|
||||
puts("reset");
|
||||
break;
|
||||
default:
|
||||
printf("%+02x");
|
||||
break;
|
||||
}
|
||||
putc('\n');
|
||||
|
||||
uint8_t command[] = {0x7e, 0xff, 0x06, cmd, 0x01, data >> 8, data, 0xef}; // command template (with feedback)
|
||||
for (uint8_t i = 0; i < LENGTH(command); i++) {
|
||||
usart_send_blocking(USART(MP3_UART), command[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** play MP3
|
||||
* @param[in] argument no argument required
|
||||
|
@ -725,14 +790,6 @@ void main(void)
|
|||
if (timer_door_closed && 0 == ((rtc_get_counter_val() - timer_door_closed) % (RTC_TICKS_SECOND / 4))) { // 1/4 second has passed since since door closed
|
||||
const uint16_t time_passed = (rtc_get_counter_val() - timer_door_closed) / RTC_TICKS_SECOND; // how many seconds have passed since door has been closed
|
||||
led_tm1637_time(time_passed / 60, time_passed % 60); // show time passed
|
||||
if (!music_played && time_passed > 10) { // start playing song after the welcome message has been played
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (2 << 8) + (rtc_get_counter_val() % MUSIC_TRACKS) + 1); // play random music track
|
||||
music_played = true; // remember we have played the music
|
||||
}
|
||||
if (!talk_played && time_passed >= 3 * 60) { // start playing talk track after 3 minutes
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (3 << 8) + (rtc_get_counter_val() % TALK_TRACKS) + 1); // play random talk track
|
||||
talk_played = true; // remember we played the talk track
|
||||
}
|
||||
}
|
||||
}
|
||||
if (door_flag) { // door switch state changed
|
||||
|
@ -743,21 +800,21 @@ void main(void)
|
|||
if (closed && 0 == timer_door_closed) { // door has been closed
|
||||
puts("door closed\n");
|
||||
timer_door_closed = rtc_get_counter_val(); // remember when the door has been closed
|
||||
music_played = false; // the music has not been played yet
|
||||
talk_played = false; // the talk has not been played
|
||||
leds_sign(true); // show on the sign that the toilet is occupied
|
||||
led_tm1637_time(0, 0); // start showing time on display
|
||||
led_tm1637_on(); // ensure the display is on
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (1 << 8) + 1); // play welcome track
|
||||
playing_state = PLAYING_STATE_INTRO; // remember we are playing the welcome message
|
||||
} else if (!closed && timer_door_closed) { // door has been opened
|
||||
puts("door opened\n");
|
||||
timer_door_closed = 0; // remember door is now open
|
||||
leds_sign(false); // show on sign the toilet is free
|
||||
led_tm1637_off(); // stop showing time
|
||||
mp3_command(MP3_CMD_STOP_PLAY, 0); // stop playing
|
||||
mp3_command(MP3_CMD_PLAY_FOLDER_FILE, (4 << 8) + (rtc_get_counter_val() % EXIT_TRACKS) + 1); // play random exit message track
|
||||
playing_state = PLAYING_STATE_EXIT; // we are playing the exit track
|
||||
}
|
||||
}
|
||||
if (mp3_rx_flag) { // data from MP3 player
|
||||
if (mp3_rx_flag) { // data from MP3 player received
|
||||
mp3_response(); // check for response
|
||||
mp3_rx_flag = false; // clear flag
|
||||
action = true; // action has been performed
|
||||
|
|
Loading…
Reference in New Issue