226 lines
6.3 KiB
C++
226 lines
6.3 KiB
C++
#include "controller.h"
|
|
#include "esmp3.h"
|
|
|
|
void Controller::handle() {
|
|
if (last_rfid_check + 500 < millis() || last_rfid_check > millis()) {
|
|
handle_rfid();
|
|
last_rfid_check = millis();
|
|
}
|
|
if (last_button_check + 10 < millis() || last_button_check > millis()) {
|
|
handle_buttons();
|
|
last_button_check = millis();
|
|
}
|
|
if (last_position_save + 10000 < millis() || last_position_save > millis()) {
|
|
current_playlist.save_current_position(audio.getFilePos());
|
|
last_position_save = millis();
|
|
//Serial.println(pm->pp_to_String().c_str());
|
|
}
|
|
}
|
|
|
|
void Controller::handle_buttons() {
|
|
if (is_button_pressed(PIN_BTN_VOL_UP)) {
|
|
log_i("BTN_VOL_UP pressed");
|
|
uint8_t vol = min(audio.getVolume()+2, 21);
|
|
log_d("Setting new volume %d", vol);
|
|
audio.setVolume(vol);
|
|
} else if (is_button_pressed(PIN_BTN_VOL_DOWN)) {
|
|
log_i("BTN_VOL_DOWN pressed");
|
|
uint8_t vol;
|
|
if ((vol = audio.getVolume()) >= 3) {
|
|
vol -= 2;
|
|
} else {
|
|
vol = 1;
|
|
}
|
|
log_d("Setting new volume %d", vol);
|
|
audio.setVolume(vol);
|
|
} else if (is_button_pressed(PIN_BTN_TRACK_NEXT)) {
|
|
log_i("BTN_TRACK_NEXT pressed");
|
|
next_track();
|
|
} else if (is_button_pressed(PIN_BTN_TRACK_PREV)) {
|
|
log_i("BTN_TRACK_PREV pressed");
|
|
prev_track();
|
|
}
|
|
}
|
|
|
|
void Controller::handle_rfid() {
|
|
if (is_rfid_present) {
|
|
byte buffer[2];
|
|
byte buffer_size = 2;
|
|
MFRC522Constants::StatusCode status = rfid->PICC_WakeupA(buffer, &buffer_size);
|
|
if (status == MFRC522Constants::STATUS_OK) {
|
|
// Card is still present.
|
|
rfid->PICC_HaltA();
|
|
} else {
|
|
Serial.printf("RFID status is %s\n", MFRC522Debug::GetStatusCodeName(status));
|
|
is_rfid_present = false;
|
|
Serial.println("No more RFID card.\n");
|
|
stop();
|
|
}
|
|
} else {
|
|
if (rfid->PICC_IsNewCardPresent()) {
|
|
if (rfid->PICC_ReadCardSerial()) {
|
|
uint32_t uid = rfid->uid.uidByte[0]<<24 | rfid->uid.uidByte[1]<<16 | rfid->uid.uidByte[2]<<8 | rfid->uid.uidByte[3];
|
|
Serial.printf("Found new rfid card with uid %x\n", uid);
|
|
is_rfid_present = true;
|
|
if (uid > 0) {
|
|
String temp = String(uid, HEX);
|
|
String s_uid = "";
|
|
for (int i=0; i<(8-temp.length()); i++) {
|
|
s_uid.concat("0");
|
|
}
|
|
s_uid.concat(temp);
|
|
|
|
String data = read_rfid_data();
|
|
|
|
play(s_uid, data.indexOf("[random]")>=0);
|
|
}
|
|
rfid->PICC_HaltA();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
String Controller::read_rfid_data() {
|
|
log_v("read_rfid_data() running...");
|
|
MFRC522::StatusCode status;
|
|
MFRC522::PICC_Type type = rfid->PICC_GetType(rfid->uid.sak);
|
|
uint16_t pageStart = 0;
|
|
uint16_t pages = 4;
|
|
uint16_t pageSize = 1;
|
|
switch(type) {
|
|
case MFRC522Constants::PICC_TYPE_MIFARE_MINI:
|
|
case MFRC522Constants::PICC_TYPE_MIFARE_1K:
|
|
case MFRC522Constants::PICC_TYPE_MIFARE_4K: {
|
|
log_v("Trying to authenticate Mifare card.");
|
|
MFRC522::MIFARE_Key key = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7};
|
|
status = rfid->PCD_Authenticate(MFRC522Constants::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &rfid->uid);
|
|
if (status == MFRC522Constants::STATUS_OK) {
|
|
log_v("Authentication succeeded.");
|
|
} else {
|
|
log_v("Authentication failed. Trying to read anyway.");
|
|
}
|
|
pageStart = 4;
|
|
break;
|
|
}
|
|
case MFRC522Constants::PICC_TYPE_MIFARE_UL:
|
|
log_v("PICC type is Mifare Ultralight. No authentication necessary.");
|
|
pages = 16;
|
|
pageSize = 4;
|
|
break;
|
|
default:
|
|
log_v("Unexpected rfid card type %s. Trying to read anyway.", MFRC522Debug::PICC_GetTypeName(type));
|
|
}
|
|
String data = "";
|
|
for (uint8_t block=pageStart; block<pages+pageStart; block+=pageSize) {
|
|
byte buffer[18];
|
|
uint8_t byte_count = 18;
|
|
status = rfid->MIFARE_Read(block, buffer, &byte_count);
|
|
if (status != MFRC522Constants::STATUS_OK) {
|
|
log_d("MIFARE_Read() failed: %s\n", String(MFRC522Debug::GetStatusCodeName(status)).c_str());
|
|
continue;
|
|
}
|
|
for (int i=0; i<16; i++) {
|
|
if (buffer[i]>=0x20 && buffer[i]<0x7F) data.concat((char)buffer[i]);
|
|
}
|
|
}
|
|
rfid->PCD_StopCrypto1();
|
|
log_v("Read rfid data: '%s'", data.c_str());
|
|
return data;
|
|
}
|
|
|
|
void Controller::play(String rfid_id, bool shuffle) {
|
|
if (!rfid_id.equals(current_playlist.get_rfid_id())) {
|
|
if (pm->has_playlist(rfid_id)) {
|
|
current_playlist = pm->get_playlist(rfid_id);
|
|
if (shuffle) {
|
|
log_i("Shuffling the playlist.");
|
|
current_playlist.shuffle();
|
|
}
|
|
play();
|
|
} else {
|
|
Serial.printf("There is no playlist for rfid_id %s\n", rfid_id.c_str());
|
|
// This is working more or less, but downloading files is really, REALLY slow. (About 4 minutes for 10 MBytes).
|
|
//download_album(rfid_id);
|
|
audio.connecttoFS(SD, "/system/sys_unknown_card.mp3");
|
|
}
|
|
} else {
|
|
if (!audio.isRunning()) {
|
|
play();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Controller::play() {
|
|
String file = current_playlist.get_current_file_name();
|
|
|
|
if (file.startsWith("/")) {
|
|
log_i("Playing file %s via connecttoFS", file.c_str());
|
|
audio.connecttoFS(SD, file.c_str(), current_playlist.get_current_time());
|
|
} else if (file.startsWith("http")) {
|
|
log_i("Playing URL %s via connecttohost", file.c_str());
|
|
audio.connecttoFS(SD, "/system/sys_connecting.mp3");
|
|
while (audio.isRunning()) {
|
|
yield();
|
|
audio.loop();
|
|
}
|
|
audio.connecttohost(file.c_str());
|
|
}
|
|
}
|
|
|
|
void Controller::next_track() {
|
|
if (current_playlist.next_track()) {
|
|
play();
|
|
}
|
|
}
|
|
|
|
void Controller::prev_track() {
|
|
uint32_t time = audio.getAudioCurrentTime();
|
|
log_d("prev_track() called. getAudioCurrentTime() returns %d", time);
|
|
if (time >= 5) {
|
|
log_d("Restarting current track.");
|
|
current_playlist.restart();
|
|
play();
|
|
} else {
|
|
if (current_playlist.prev_track()) {
|
|
play();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Controller::stop() {
|
|
if (audio.isRunning()) {
|
|
current_playlist.set_current_time(audio.stopSong());
|
|
}
|
|
}
|
|
|
|
bool Controller::is_button_pressed(uint8_t pin) {
|
|
//log_d("Button %d state is %d", pin, digitalRead(pin));
|
|
if (!digitalRead(pin)) {
|
|
// Button is pressed - let's debounce it.
|
|
if (button_pressed == pin) {
|
|
if (button_pressed_since + 150 < millis() && !button_already_processed) {
|
|
button_already_processed = true;
|
|
return true;
|
|
}
|
|
} else {
|
|
button_pressed = pin;
|
|
button_pressed_since = millis();
|
|
button_already_processed = false;
|
|
}
|
|
} else {
|
|
if (button_pressed == pin) {
|
|
button_pressed = 0;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Controller::eof_mp3(String info) {
|
|
log_d("Handling eof. Keep playing until the file is finished.");
|
|
while(audio.isRunning()) { audio.loop(); yield; }
|
|
if (info.startsWith("sys_")) {
|
|
log_d("File ending was a system audio file. Not running next_track.");
|
|
} else {
|
|
next_track();
|
|
}
|
|
} |