//BEZDRAT ver2 #define noDEBUG #define pinLCD 10 #define pinSetup 13 #define btnSelect 0x01 //tlacitka #define btnLeft 0x02 #define btnRight 0x03 #define btnUp 0x04 #define btnDown 0x05 #define btnSelect2 0x81 //tlacitka s dlouhym stiskem #define btnLeft2 0x82 #define btnRight2 0x83 #define btnUp2 0x84 #define btnDown2 0x85 #define buflen 250 #include #ifdef DEBUG #define pinRX 11 #define pinTX 12 #include SoftwareSerial uart(pinRX, pinTX); #endif #ifndef DEBUG #define uart Serial #endif LiquidCrystal lcd(8, 9, 4, 5, 6, 7); const char AT_M1[] PROGMEM = "AT+M1"; const char AT_M2[] PROGMEM = "AT+M2"; const char AT_MT[] PROGMEM = "AT+MT"; const char AT_MF[] PROGMEM = "AT+MF"; const char AT_QM[] PROGMEM = "AT+QM"; const char AT_CM01[] PROGMEM = "AT+CM01"; const char AT_CM02[] PROGMEM = "AT+CM02"; const char AT_CM03[] PROGMEM = "AT+CM03"; const char AT_CB[] PROGMEM = "AT+CB"; const char AT_CC[] PROGMEM = "AT+CC"; const char AT_CD[] PROGMEM = "AT+CD"; const char AT_AA04[] PROGMEM = "AT+AA04"; const char AT_AA05[] PROGMEM = "AT+AA05"; const char AT_AA06[] PROGMEM = "AT+AA06"; const char AT_AA07[] PROGMEM = "AT+AA07"; const char AT_CF[] PROGMEM = "AT+CF"; const char AT_CE[] PROGMEM = "AT+CE"; const char AT_MK[] PROGMEM = "AT+MK"; const char AT_CZ[] PROGMEM = "AT+CZ"; const char AT_QA[] PROGMEM = "AT+QA"; char uartBuffer[buflen + 2]; char TS[] = "TS+"; char MU[] = "MU+"; char ER[] = "ER+"; bool disp, fileName; byte seq, uartIndex, cmdIndex, currMode, currVol, KB; unsigned long uartTime, sysTime, currFile, totalFiles, timeFile, elapsedFile; #ifdef DEBUG void _printBuffer() { Serial.print("buflen: "); Serial.println(uartIndex); for (byte i = 0; i < uartIndex; i++) { byte c = uartBuffer[i]; Serial.print(char(c)); Serial.print(":"); Serial.print(c, HEX); Serial.print(" "); if (c == 0) Serial.println(); } } #endif void clearValues() { currFile = 0; totalFiles = 0; timeFile = 0; elapsedFile = 0; currMode = 0; fileName = false; } //------------------------------------------------------------------------------------------ void showDisplay() { digitalWrite(pinLCD, HIGH); disp = true; seq = 1; } void showMode() { lcd.setCursor(10, 0); for (byte i = 10; i < 16; i++) lcd.print(" "); lcd.setCursor(10, 0); switch (currMode) { case 1: lcd.clear(); lcd.print(F("Bluetooth")); break; case 2: lcd.print(F(" USB")); break; case 3: lcd.print(F(" TF")); break; } } void showM12() { lcd.setCursor(0, 0); for (byte i = 0; i < 10; i++) lcd.print(" "); lcd.setCursor(0, 0); lcd.print(currFile); lcd.print("/"); lcd.print(totalFiles); } void showTime(unsigned long t) { int h = t / 60; int m = t % 60; if (h < 100) lcd.print(" "); if (h < 10) lcd.print(" "); lcd.print(h); lcd.print(":"); if (m < 10) lcd.print("0"); lcd.print(m); } void showMT() { lcd.setCursor(10, 0); for (byte i = 10; i < 16; i++) lcd.print(" "); lcd.setCursor(10, 0); if (timeFile) showTime(timeFile - elapsedFile); else showTime(elapsedFile); } void showStatus(char* stat, bool force) { if (force) showDisplay(); lcd.setCursor(0, 1); for (byte i = 0; i < 16; i++) lcd.print(" "); lcd.setCursor(0, 1); lcd.print(stat); } void showError(char* err) { showDisplay(); lcd.setCursor(10, 0); for (byte i = 10; i < 16; i++) lcd.print(" "); lcd.setCursor(12, 0); lcd.print(err); } void showSys() { lcd.clear(); showMode(); lcd.setCursor(0, 1); lcd.print((millis() / 60000) + 1); lcd.print(" min; <"); lcd.print(currVol); delay(1000); clearValues(); } //------------------------------------------------------------------------------------------ void flushData() { while (uart.available()) byte i = uart.read(); } void sendCmd(const char* cmd) { char c[16]; byte n = strlen_P(cmd); for (byte i = 0; i < n; i++) c[i] = pgm_read_byte_near(cmd + i); c[n] = '\0'; flushData(); uart.println(c); int w = 0; while (!uart.available()) { //cekani na odpoved delay(1); w++; if (w > 2048) { char e[] = "ER+A"; showError(e); break; } } #ifdef DEBUG Serial.print(w); Serial.print("mS ---> "); Serial.println(c); #endif } bool testValues() { //currFile, timeFile if (totalFiles == 0) { sendCmd(AT_M2); return true; } if (currFile == 0) { sendCmd(AT_M1); return true; } if (timeFile == 0) { sendCmd(AT_MT); return true; } if (!fileName) { sendCmd(AT_MF); return true; } return false; } byte keyPressed() { if (analogRead(0) >= 750) return 0; uint8_t result = 0xff; unsigned long pressTime = 0; word n = 0; //analogRead(0); word p = 0; for (byte i = 0; i < 8; i++) { word k = analogRead(0); if (k < 750) { n += k; p++; } delay(8); } if (p < 8) return 0; n = n / p; if (n < 88) result = btnRight; //Vpravo(RIGHT) if ((n >= 88) && (n < 150)) result = btnUp; //Nahoru(UP) if ((n >= 150) && (n < 350)) result = btnDown; //Dolu(DOWN) if ((n >= 350) && (n < 500)) result = btnLeft; //Vlevo(LEFT) if ((n >= 500) && (n < 750)) result = btnSelect; //Vyber(SELECT) if (result < 0xff) { // test dlouhy stisk unsigned long t = millis(); bool w = true; while (analogRead(0) < 750) { pressTime = millis() - t; if (w && (pressTime > 1200)) { w = false; lcd.setCursor(14, 0); lcd.print(" *"); } } if (pressTime > 1200) result = result | 0x80; //byl dlouhy stisk //if (pressTime < 50) result = 0xff; //prilis kratky stisk #ifdef DEBUG Serial.print("readKey ------------------ "); Serial.print(result, HEX); Serial.print("; analog: "); Serial.println(n); #endif } if (result == 0xff) result = 0; return result; } void selectMode() { byte oldMode = currMode; lcd.clear();//1234567890123456 lcd.print(F("up: TF|down: USB")); lcd.setCursor(0, 1); lcd.print(F("left: Bluetooth")); unsigned long t = millis(); do { byte k = keyPressed(); if (k) switch (k) { case btnUp: currMode = 3; t = 0; break; case btnDown: currMode = 2; t = 0; break; case btnLeft: currMode = 1; t = 0; break; default: t = 0; break; } } while ((millis() - t) < 8000); if (currMode != oldMode) switch (currMode) { case 1: sendCmd(AT_CM01); break; case 2: sendCmd(AT_CM02); break; case 3: sendCmd(AT_CM03); break; } clearValues(); } //------------------------------------------------------------------------------------------ bool evalMV(char* responseStr) { char* p = strstr(responseStr, "QA+"); if (p == NULL) return false; p += 3; currVol = strtoul(p, NULL, 10); return true; } bool evalM1(char* responseStr) { char* p = strstr(responseStr, "M1+"); if (p == NULL) return false; p += 3; currFile = strtoul(p, NULL, 16); return true; } bool evalM2(char* responseStr) { char* p = strstr(responseStr, "M2+"); if (p == NULL) return false; p += 3; totalFiles = strtoul(p, NULL, 16); return true; } bool evalMT(char* responseStr) { char* p = strstr(responseStr, "MT+"); if (p == NULL) return false; p += 3; timeFile = strtoul(p, NULL, 16); return true; } bool evalMK(char* responseStr) { char* p = strstr(responseStr, "MK+"); if (p == NULL) return false; p += 3; elapsedFile = strtoul(p, NULL, 16); return true; } bool evalMF(char* responseStr) { char* p = strstr(responseStr, "MF+"); if (p == NULL) return false; #ifdef DEBUG Serial.println("evalMF"); Serial.println(p); #endif char fname[48]; fname[47] = '\0'; fileName = true; p += 3; strncpy(fname, p, 47); p = fname; #ifdef DEBUG Serial.println(p); #endif lcd.setCursor(0, 1); for (byte i = 0; i < 16; i++) lcd.print(" "); lcd.setCursor(0, 1); //p += 3; int n = strlen(p); if (n > 16) for (byte i = 1; i < 8; i++) if (p[n - i] == '.') { p[n - i] = '\0'; //odrizne priponu break; } #ifdef DEBUG Serial.println(p); #endif n = strlen(p); if (n > 16) { p[8] = '\0'; lcd.print(p); lcd.print("~"); #ifdef DEBUG Serial.println(p); #endif p += (n - 7); } lcd.print(p); #ifdef DEBUG Serial.println(p); Serial.println("---"); #endif showDisplay(); return true; } bool evalMode(char* responseStr) { byte cm = currMode; if (strcmp(responseStr, "QM+01") == 0) cm = 1; if (strcmp(responseStr, "QM+02") == 0) cm = 2; if (strcmp(responseStr, "QM+03") == 0) cm = 3; if (currMode != cm) { currMode = cm; return true; } return false; } unsigned long evalStatus(char* responseStr, char* pattern) { char* p = strstr(responseStr, pattern); if (p == NULL) return -1; p += 3; return strtoul(p, NULL, 16);; } char* responseItem() { char* result = NULL; if (cmdIndex < uartIndex) { result = &uartBuffer[cmdIndex]; cmdIndex += (strlen(result) + 1); } return result; } void response() { #ifdef DEBUG _printBuffer(); #endif cmdIndex = 0; char* responseStr; do { responseStr = responseItem(); if (responseStr == NULL) break; #ifdef DEBUG Serial.println(responseStr); #endif if (evalMF(responseStr)) continue; if (evalMode(responseStr)) showMode(); if (evalM1(responseStr)) showM12(); if (evalM2(responseStr)) showM12(); if (evalMT(responseStr)) showMT(); if (evalMK(responseStr)) showMT(); if (evalMV(responseStr)) ; switch (evalStatus(responseStr, TS)) { case 0: {char txt[] = "BT odpojen"; showStatus(txt, false);} break; case 1: {char txt[] = "BT pripojen"; showStatus(txt, true);} break; case 2: {char txt[] = "BT hraje"; showStatus(txt, false);} break; } switch (evalStatus(responseStr, MU)) { case 1: {char txt[] = "USB vlozen"; showStatus(txt, true);} break; case 2: {char txt[] = "USB vyjmut"; showStatus(txt, true);} break; case 3: {char txt[] = "TF vlozena"; showStatus(txt, true);} break; case 4: {char txt[] = "TF vyjmuta"; showStatus(txt, true);} break; } if (evalStatus(responseStr, ER) != -1) showError(responseStr); } while (true); uartTime = millis(); uartIndex = 0; return; } void addBuffer(char c) { //filtrovani znaku uartTime = millis(); if (byte(c) == 10) { uartBuffer[uartIndex] = '\0'; goto valid; } if ((c == '+') || (c == '.')) { uartBuffer[uartIndex] = c; goto valid; } if ((byte(c) >= 48) && (byte(c) <= 57)) { uartBuffer[uartIndex] = c; goto valid; } if ((byte(c) >= 65) && (byte(c) <= 90)) { uartBuffer[uartIndex] = c; goto valid; } if ((byte(c) >= 97) && (byte(c) <= 122)) { uartBuffer[uartIndex] = c; goto valid; } return; valid: uartIndex++; uartBuffer[uartIndex] = '\0'; if (uartIndex >= buflen) { uartIndex = 0; char err[] = "ER+B"; showError(err); flushData(); } } //------------------------------------------------------------------------------------------ void setup() { uartBuffer[buflen + 1] = '\0'; uartIndex = 0; cmdIndex = 0; currMode = 0; currVol = 0xff; seq = 1; KB = 0; pinMode(pinSetup, OUTPUT); digitalWrite(pinSetup, HIGH); lcd.begin(16, 2); lcd.clear(); showDisplay(); pinMode(pinLCD, OUTPUT); digitalWrite(pinLCD, HIGH); clearValues(); lcd.print(F("Bezdratak v.2")); lcd.setCursor(0, 1); lcd.print(F("MP3 a Bluetooth")); uart.begin(9600); #ifdef DEBUG Serial.begin(9600); Serial.println(F("Bezdrat2 start")); #endif delay(1000); uartTime = millis(); sysTime = millis(); sendCmd(AT_QM); } void loop() { while (uart.available()) addBuffer(uart.read()); if (!KB) KB = keyPressed(); if (uartIndex > 0) { if ((millis() - uartTime) > 1000) response(); return; } if (KB) { if (disp) seq = 1; else seq = 3; sysTime = millis(); digitalWrite(pinLCD, HIGH); if (disp) switch (KB) { case btnSelect: sendCmd(AT_CB); break; //play/pause case btnLeft: if (currMode > 1) sendCmd(AT_CD); break; //zpet o 1 case btnRight: if (currMode > 1) sendCmd(AT_CC); break; //vpred o 1 case btnUp: sendCmd(AT_CE); currVol = 0xff; break; //zesil case btnDown: sendCmd(AT_CF); currVol = 0xff; break; //zeslab case btnSelect2: selectMode(); break; case btnLeft2: if (currMode > 1) sendCmd(AT_AA07); else showSys(); break; //zpet o slozku case btnRight2: if (currMode > 1) sendCmd(AT_AA06); else showSys(); break; //vpred o slozku case btnUp2: sendCmd(AT_CZ); break; case btnDown2: showSys(); break; } disp = true; KB = 0; return; } if ((millis() - sysTime) > 1000) { seq++; sysTime = millis(); if (currMode == 0) sendCmd(AT_QM); if (currMode > 1) { if (testValues()) seq = 1; } } if ((seq % 5) == 0) { seq++; if (currVol == 0xff) sendCmd(AT_QA); else if (disp && (currMode > 1)) sendCmd(AT_MK); } if (seq > 80) { seq = 1; digitalWrite(pinLCD, LOW); disp = false; } }