/* * Radio I2C: * adresa: 16 (0x10) * adresa: 17 (0x11) * adresa: 96 (0x60) * */ #define noDBG //define SETD 12 #define CYKLUS_COUNT 8 //pocet cteni RDS casu, nez se aktualizuji RTC #define MAX_TRY 32 //maximalni pocet pokusu cteni RDS casu pro naladenou stanici #define KEY_TIME 16 //casova porodleva tlacitek #define EPROM_FQ 1 //adresa ulozeni stanice v eprom #define PIN_UP 5 //piny pro tlacitka #define PIN_DN 6 #define PIN_PW 9 #include #include #include #include #include RDA5807 rx; Ds1302 rtc(4, 2, 3); // RST, DAT, CLK TM1637Display dsp(8, 7); // CLK, DIO Ds1302::DateTime dt; int minutRDS[CYKLUS_COUNT]; //minut celkem int elapsed = 0; //cyklus byte cyklus_index = 0; //poradi prevzeti casu z RDS byte jas = 11; //jas displeje 8 - 15 byte adjustDay = 0; //den, pro aktualizaci RDS, cas se aktualizuje jednou denne byte tryRDS = 0; //pocet neuspenych pokusu cteni casu z RDS byte debug1, debug2; //hodnoty ladeni bool stoppedRDS = false; //po precteni casu RDS bude pauza bool colon = true; //blikani dvojtecky bool writeFq = false; //stamice se do eprom uklada za 20sec po naladeni bool testMode = false; #ifdef DBG byte ddebug1 = 0xff; byte ddebug2 = 0xff; void debugWire() { Serial.begin(9600); while (!Serial) {} Serial.println (); Serial.println ("Hledam I2C ....."); Wire.begin(); for (byte i = 1; i < 120; i++) { Wire.beginTransmission (i); if (Wire.endTransmission () == 0) { Serial.print ("Nalezena adresa: "); Serial.print (i, DEC); Serial.print (" (0x"); Serial.print (i, HEX); Serial.println (")"); delay (1); } } Serial.println ("Hotovo"); testMode = true; } #endif //-- inicializace ------------------------------------------------------------------------------- bool initRadio() { rx.setup(); rx.setRDS(true); rx.setVolume(3); delay(512); rx.setRDS(true); rx.setRdsFifo(true); rx.setLnaPortSel(3); rx.setAFC(true); rx.setMono(true); //rx.setFrequency(freq); //9930 evropa2, 10200 CRO2, 10430 F1 delay(512); //rx.powerUp(); return true; } void initDisplay() { delay(1024); dsp.clear(); dsp.setBrightness(jas); } void initRTC() { rtc.init(); rtc.getDateTime(&dt); #ifdef SETD rtc.halt(); while (!rtc.isHalted()); dt.day = SETD; rtc.setDateTime(&dt); rtc.start(); debug1 = 0xdc; debug2 = dt.day; #endif #ifdef DBG Serial.print(dt.day); Serial.print("."); Serial.print(dt.month); Serial.print(".");Serial.println(dt.year); Serial.print(dt.hour); Serial.print(":"); Serial.print(dt.minute); Serial.print(" - ");Serial.println(dt.dow); #endif } //-- Display ----------------------------------------------------------------------------------------- void showReset() { dsp.showNumberDec(dt.day, true, 2, 0); dsp.showNumberDec(dt.month, true, 2, 2); delay(1024); } void showHM() { rtc.getDateTime(&dt); byte c; if (testMode) { c = 0b01000000; } else { if (colon) c = 0b01000000; else c = 0b00000000; colon = !colon; } word n = (dt.hour * 100) + dt.minute; dsp.showNumberDecEx(n, c, true); //dsp.showNumberDecEx(dt.minute, c, true, 2, 2); } void showDebug() { #ifdef DBG if ((ddebug1 != debug1) || (ddebug2 != debug2)) { Serial.print("debug1 = "); Serial.print(debug1, HEX); Serial.print("; debug2 = "); Serial.println(debug2); } ddebug1 = debug1; ddebug2 = debug2; #endif if ((debug1 + debug2) == 0) { showHM(); return; } dsp.showNumberHexEx(debug1, 0b01000000, true, 2, 0); if (debug2 > 99) debug2 = 99; dsp.showNumberDec(debug2, true, 2, 2); } void showFq() { word f = rx.getFrequency(); dsp.showNumberDec(f / 10, true); // elapsed = 0; } void showInfo() { if (testMode) showDebug(); else showHM(); } void jasInc() { if (jas < 15) jas++; dsp.setBrightness(jas); showInfo(); } void jasDec() { if (jas > 8) jas--; dsp.setBrightness(jas); showInfo(); } //-- RTC -------------------------------------------------------------------------------------------- void setRTC(byte hh, byte mm) { rtc.halt(); while (!rtc.isHalted()); dt.hour = hh; dt.minute = mm; dt.second = 0; rtc.setDateTime(&dt); rtc.start(); #ifdef DBG Serial.println("setRTC"); #endif } void updateTime(int m) { byte H = m / 60; byte M = m % 60; rtc.getDateTime(&dt); adjustDay = dt.day; #ifdef DBG Serial.print("adjustDay = "); Serial.println(dt.day); #endif if ((dt.hour != H) || (dt.minute != M) || (dt.second > 10)) { setRTC(H, M); if (testMode) { showHM(); delay(1024); } else { showReset(); } } debug1 = 0xad; debug2 = dt.second; } //-- radio / RDS ------------------------------------------------------------------------------------- word getFq() { word result = 8750 + (10 * EEPROM.read(EPROM_FQ)); if ((result < 8750) || (result > 10800)) { rx.setFrequency(9400); result = rx.getFrequency(); if ((result < 8750) || (result > 10800)) result = 8750; } return result; } void updateFq(word f) { byte n = (f - 8750) / 10; if (n <= 205) EEPROM.update(EPROM_FQ, n); writeFq = false; } void setFreq(byte up) { cyklus_index = 0; tryRDS = 0; word f = rx.getFrequency(); if (up) { if (f < 10800) rx.setFrequencyUp(); else rx.setFrequency(8750); } else { if (f > 8750) rx.setFrequencyDown(); else rx.setFrequency(10800); } writeFq = true; showFq(); } bool testRDS() { //pokud nesedi predesly, nema smysl jet dal, pojede znovu if (cyklus_index > 0) { int n = (minutRDS[cyklus_index] - minutRDS[cyklus_index - 1]); bool result = ((n == 1) || (n == 2)); if (result) debug1 = 0xd0 + cyklus_index; else debug1 = 0xe0 + cyklus_index; debug2 = n; if (!result) tryRDS++; return result; } return true; } bool timeRDS() { bool result = ((rx.getRdsReady() && rx.hasRdsInfo())); if (result) { char *rdsTime; rdsTime = rx.getRdsLocalTime(); result = false; if (rdsTime != NULL ) { if (strlen(rdsTime) == 5) { char h[3] = {0,0,0}; char m[3] = {0,0,0}; strncpy(h, &rdsTime[0], 2); strncpy(m, &rdsTime[3], 2); byte H = atoi(h); byte M = atoi(m); minutRDS[cyklus_index] = (60 * H) + M; debug1 = 0xd0 + cyklus_index; debug2 = 1; result = rdsTime[2] == ':'; } } } return result; } //-- tlacitka ---------------------------------------------------------------------------- bool shiftPressed() { return (!digitalRead(PIN_PW)); } byte keyPressed() { byte result = 0; byte cnt = 0; bool pressed; do { pressed = false; if (shiftPressed()) { bitSet(result, 7); //80 - shift } if (!digitalRead(PIN_DN)) { bitSet(result, 0); //01 - predesly pressed = true; } if (!digitalRead(PIN_UP)) { bitSet(result, 1); //02 - dalsi pressed = true; } if (pressed) { cnt++; delay(8); } } while (pressed && (cnt < KEY_TIME)); if (cnt < KEY_TIME) result = 0; return result; } //-- Main ------------------------------------------------------------------------------- void setup() { #ifdef DBG debugWire(); #endif pinMode(PIN_UP, INPUT); pinMode(PIN_DN, INPUT); pinMode(PIN_PW, INPUT); initRTC(); initRadio(); initDisplay(); rx.setFrequency(getFq()); showReset(); } void loop() { elapsed++; bool s = shiftPressed(); byte k = keyPressed(); if (k || s) { if (s) showFq(); //pri stisknutem shiftu zobrazuje naladeny kmitocet if (k == 1) jasDec(); // jas - if (k == 2) jasInc(); //jas + if ((k == 0x81) || (k == 0x82)) setFreq(k == 0x82); //ladeni vpred / zpet if (k == 0x83) { while (keyPressed()); //pocka na key up testMode = !testMode; //stisk vech tri tlacitek najednou nahodi/shodi test mod } //debug1 = k; debug2 = s; return; } if ((elapsed % 125) == 0) showInfo(); if (elapsed > 2500) { elapsed = 0; stoppedRDS = ((adjustDay != 0) && (adjustDay == dt.day)); //false; if (stoppedRDS) debug1 = 0xdb; else debug1 = 0xda; debug2 = tryRDS; if (writeFq) updateFq(rx.getFrequency()); } delay(8); if (stoppedRDS) return; //zatim RDS netestovat if (tryRDS > MAX_TRY) { //vycerpan pocet pokusu cteni RDS pro naladenou stanici debug1 = 0xef; debug2 = tryRDS; return; } if (timeRDS()) { stoppedRDS = true; if (cyklus_index < CYKLUS_COUNT) { if (testRDS()) cyklus_index++; else cyklus_index = 0; } if (cyklus_index >= CYKLUS_COUNT) { updateTime(minutRDS[CYKLUS_COUNT - 1]); cyklus_index = 0; } delay(512); } }