//http://playground.arduino.cc/Code/Keypad#define MAXmenu 4#define ledPin 13#define blPin 7//심볼 정의 키패드의 버튼문자 키[7][2] ={ {'L', 'P'}, //LED, POWER {'I', 'D'}, //INFO, DISPLAY {'1', '2 '}, //프리셋 {'3', '4'}, //1 {'5', '6'}, //부터 6 {'M', 'm'}, //M ODE, MEM {'<', '>'} //아래로, 위로};바이트 rowPins[7] ={11, 12, 10, 17, 9, 16, 8}; //키패드바이트의 행 핀아웃에 연결 colPins[2] ={15, 14}; //키패드의 열 핀아웃에 연결//키패드 kpd =Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );Keypad 키패드 =Keypad( makeKeymap(keys), rowPins, colPins, 7, 2 ); 부울 베이스 =0, dspl =0, memdisplay =0, mempress =0, adj =0; 부울 ledPin_state, power_state;int 메뉴;int 볼륨, volumeOld =5;int 주파수, frequencyOld;int txtl =0, temparray =0; int samples[5];unsigned int status[6];unsigned long timeprevious =0, timeprev =0;// EEPROM objectAT24CX mem;RTC_DS1307 rtc;//(clk, din, dc, ce, rst)LCD5110 lcd(6, 5, 4, 2, 3);// RDA5807 칩의 인스턴스 생성 radioRDA5807M radio;/// RDS 파서 가져오기RDSParser rds;extern unsigned char SmallFont[];extern uint8_t signal5[];extern uint8_t signal4[];extern uint8_t signal3[];extern uint8_t signal2[];extern uint8_t signal1[];//--------------------------SETUP---- ------------------------------//설정 무효화(){ analogReference(EXTERNAL); Serial.begin(9600); Wire.begin(); // 라디오 초기화 radio.init(); radio.debugEnable(); //화면 초기화 lcd.InitLCD(); lcd.clrScr(); //lcd.setContrast(45); //기본값이 좋지 않으면 조정 lcd.setFont(SmallFont); lcd.enableSleep(); //대기 모드 power_state =0; //전원이 연결되어 있을 때 기기의 전원을 켜지 않음(대기 모드) //키보드 키패드 초기화.addStatedEventListener(keypadEvent); // 이 키패드에 대한 이벤트 리스너를 추가합니다. 키패드.setHoldTime(1500); 핀모드(LED핀, 출력); // 디지털 핀을 출력으로 설정합니다. 핀모드(블핀, 출력); // 디지털 핀을 출력으로 설정합니다. 디지털 쓰기(LED 핀, LOW); // LED를 끕니다. digitalWrite(blPin, LOW); // BL 끄기(대기 모드) ledPin_state =digitalRead(ledPin); // 초기 LED 상태를 저장합니다. LED가 켜져 있을 때 HIGH. //rtc를 조정해야 하는 경우 주석 처리를 제거합니다. /*if (! rtc.isrunning()) { Serial.println("RTC가 실행되고 있지 않습니다!"); // 다음 줄은 RTC를 이 스케치가 컴파일된 날짜 및 시간으로 설정합니다. rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // 이 줄은 명시적 날짜 및 시간으로 RTC를 설정합니다. 예를 들어 // 2014년 1월 21일 오전 3시에 설정하려면 다음을 호출합니다. //rtc.adjust(DateTime(2018, 3, 13, 22, 33, 0) ); }*/ // 마지막 주파수 값 읽기 frequency =mem.readInt(201); 볼륨 =2; // 시작 메뉴의 볼륨 레벨 =1; //(volume <0) volume =0인 경우 시작 시 VOLUMME 모드를 표시합니다. if (볼륨> 15) 볼륨 =15; if (주파수 <0) 주파수 =0; if (주파수> 210) 주파수 =210; 쓰기 등록(0x02, 0xC00d); // 0xC00d를 Reg.2에 씁니다. ( soft reset, enable,RDS, ) //bbz canal(frequency); // RDS 데이터에 대한 정보 체인을 설정합니다. radio.attachReceiveRDS(RDS_process); rds.attachServicenNameCallback(디스플레이 서비스 이름); //rds.attachTimeCallback(디스플레이 타임); //나중에 사용하기 위해. RDS 신호가 약할 때 매우 부정확합니다. rds.attachTextCallback(DisplayText);}//--------------------------설치 종료-------------- ----------------------////------------------------ --LOOP----------------------------------------//무효 루프(){ if ( 주파수 !=frequencyOld) { frequencyOld =주파수; mem.writeInt(201, 빈도); 운하(빈도); } if (볼륨 !=volumeOld) { volumeOld =볼륨; WriteReg(5, 0x84D0 | 볼륨); } //키보드 읽기 char key =키패드.getKey(); //RDS 데이터 확인 radio.checkRDS(); // 0.6초마다 온도 프로브를 5번 읽고 평균 부동 평균을 계산합니다. unsigned long timenow =millis(); if ((unsigned long)(timenow - timeprevious)> 600) { timeprevious =timenow; 샘플[임시] =analogRead(A7); 임시 배열++; } if (temparray ==5) { // 판독값의 평균 계산 평균 =0; for (int i =0; i <5; i++) { 평균 +=샘플[i]; } printTemp(평균); 임시 배열 =0; } // MEM 디스플레이를 위한 4초 타임아웃 및 unsigned long 입력 dabar =millis(); if (멤프레스 ==1) { timeprev =dabar; 메모리 디스플레이 =1; 황후 =0; } if (memdisplay ==1) { if ((unsigned long)(dabar - timeprev) <4000) { memdisplay =1; } else { memdisplay =0; } } /*시간 조정 지침:1. 직렬 모니터를 실행합니다. 2. 9600 boud를 설정합니다. 3. Enter 키를 눌러 직렬 읽기를 활성화합니다. 4. hXX를 작성합니다. 여기서 XX는 일부 시간 서버에서 읽는 현재 시간이고 Enter 키를 눌러 RTC 시간을 조정합니다. 직렬 모니터는 "Hours XX"를 기록해야 합니다. 5. mXX를 기록합니다. 여기서 XX는 특정 시간 서버에서 읽는 현재 분이고 Enter 키를 눌러 RTC 분을 조정합니다. 직렬 모니터는 "분 XX"를 기록해야 합니다. 6. sXX를 기록합니다. 여기서 XX는 일부 시간 서버에서 읽는 현재 초이고 Enter 키를 눌러 RTC 초를 조정합니다. 직렬 모니터는 "초 XX"를 써야 합니다. 7. 시간만 조정할 수 있습니다. 즉. 일광 절약 시간이 변경되었을 때. 8. 시간만 수정해야 하는 경우 초만 조정할 수 있습니다. 9. RTC를 0(년, 월, 일 등)에서 조정해야 하는 경우 RTC 조정 설명 라인의 주석을 제거하고 스케치를 업로드합니다. */ 현재 날짜 시간 =rtc.now(); if (Serial.available()> 0) { char t =Serial.read(); switch (t) { case ('h'):{ unsigned int hours =Serial.parseInt(); rtc.adjust(DateTime(now.year(), now.month(), now.day(), 시간, now.minute(), now.second())); Serial.println(F("시간")); Serial.println(시간); 부서지다; } 케이스('m'):{ unsigned int mins =Serial.parseInt(); rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), mins, now.second())); Serial.println(F("분")); Serial.println(분); 부서지다; } 케이스('s'):{ unsigned int sec =Serial.parseInt(); rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), sec)); Serial.println(F("초")); Serial.println(초); 부서지다; } } } //LCD에 각종 정보 표시 printSignalStrength(); 인쇄라인(); 인쇄시간(); 인쇄주파수(); 인쇄 스테레오(); 인쇄 모드(); 인쇄메뉴(); 인쇄날짜(); lcd.update();}//------------------------- 루프 끝---------------- ----------------------//void printSignalStrength() //0000에서 1111까지(0-63){ unsigned int sig; 상태 읽기(); 시그 =상태[1] / 1000; if ((sig>=0) &&(sig <=12)) { lcd.drawBitmap(1, 1, signal1, 17, 6); } if ((sig>=13) &&(sig <=24)) { lcd.drawBitmap(1, 1, signal2, 17, 6); } if ((sig>=25) &&(sig <=36)) { lcd.drawBitmap(1, 1, signal3, 17, 6); } if ((sig>=37) &&(sig <=48)) { lcd.drawBitmap(1, 1, signal4, 17, 6); } if (sig>=49) { lcd.drawBitmap(1, 1, signal5, 17, 6); }} 무효 printLines(){ lcd.drawLine(0, 9, 84, 9); lcd.drawLine(0, 39, 84, 39);}void printTemp(float average) //최적화 가능 :){ 평균 /=5; 평균 =1023 / 평균 - 1; 평균 =51700 / 평균; 플로트 스타인하트; steinhart =평균 / 50000; // (R/Ro) steinhart =log(steinhart); // ln(R/Ro) steinhart // 3950; // 1/B * ln(R/Ro) steinhart +=1.0 / (25 + 273.15); // + (1/To) steinhart =1.0 / steinhart; // steinhart 반전 -=273.15; // 섭씨 변환 int tmp =round(steinhart); lcd.printNumI(tmp, 60, 1, 2); lcd.print(F("~C"), 72, 1);}/// RDS mode.void DisplayServiceName(char *name){ lcd.print(name, 18, 22);}void DisplayText(char *text){ //두 번째 RDS 줄 스크롤 lcd.print(text, txtl, 30); txtl =txtl - 66; if (txtl ==-396) txtl =0;}무효 printTime(){ DateTime now =rtc.now(); lcd.printNumI(지금.시간(), 24, 1, 2, '0'); lcd.print(":", 36, 1); lcd.printNumI(now.minute(), 42, 1, 2, '0');}void printDate(){ if (dspl ==1) { //디스플레이 키가 눌렸는지 확인 ClearRDS(); 지금 날짜 시간 =rtc.now(); lcd.printNumI(now.year(), 12, 22, 4); lcd.print(".", 36, 22); lcd.printNumI(now.month(), 42, 22, 2, '0'); lcd.print(".", 54, 22); lcd.printNumI(now.day(), 60, 22, 2, '0'); int dw =now.dayOfTheWeek(); 스위치 (dw) { 경우 0:lcd.print(F("Sekmadienis"), CENTER, 30); //sdram break를 저장하기 위한 일요일 F() 매크로; 사례 1:lcd.print(F("피르마디에니스"), CENTER, 30); //월요일 등... break; 사례 2:lcd.print(F("안트라디에니스"), CENTER, 30); 부서지다; 사례 3:lcd.print(F("Treciadienis"), CENTER, 30); 부서지다; 사례 4:lcd.print(F("Ketvirtadienis"), CENTER, 30); 부서지다; 사례 5:lcd.print(F("Penktadienis"), CENTER, 30); 부서지다; 사례 6:lcd.print(F("Sestadienis"), CENTER, 30); 부서지다; } lcd.update(); 지연(4000); //최적의 ClearRDS()가 아님; dpl =0; }} 무효 printMode(){ lcd.print(F("모드 "), 0, 41);} 무효 printMenu(){ if (메뉴 ==1) { lcd.print(F("볼륨 "), 30, 41); if (볼륨 <0) { lcd.print(F("XX"), 72, 41); } else lcd.printNumI(볼륨 + 1, 72, 41, 2, '0'); } if (메뉴 ==2) { lcd.print(F("자동 조정"), 30, 41); } if (메뉴 ==3) { lcd.print(F("MAN.-TUNE"), 30, 41); } if (메뉴 ==4) { lcd.print(F("저음"), 30, 41); if (저음 ==0) { lcd.print(F("OFF"), 66, 41); } else lcd.print(F(" 켜짐"), 66, 41); }}void printFreq() //현재 주파수 표시{ int frHundr, frDec; 부호 없는 int fr; fr =870 + 주파수; frHundr =fr / 10; frDec =fr % 10; lcd.printNumI(frHundr, 30, 12, 3); lcd.print(F("."), 48, 12); lcd.printNumI(frDec, 54, 12, 1); lcd.print(F("MHz"), 66, 12);}void printStereo(){ if (memdisplay ==1) { //MEM 키를 눌렀을 경우 lcd.print(F("MEM>"), 0 , 12); } //스테레오 감지 else if ((status[0] &0x0400) ==0) lcd.print(F("( )"), 0, 12); // MONO를 의미합니다. else lcd.print (F("(ST)"), 0, 12); // STEREO를 의미함} 무효 검색(바이트 디렉토리) //자동 검색{ 바이트 i; //위 또는 아래를 찾습니다. if (!directec) WriteReg(0x02, 0xC30d); 그렇지 않으면 WriteReg(0x02, 0xC10d); for (i =0, i <10, i++) { delay(200); 상태 읽기(); if (상태[0] &0x4000) { 빈도 =상태[0] &0x03ff; 부서지다; } }}void canal( int canal) //직접 주파수{ 바이트 numberH, numberL; numberH =운하>> 2; numberL =((관 및 3) <<6 | 0x10); Wire.beginTransmission(0x11); Wire.write(0x03); Wire.write(숫자H); // 주파수를 비트 15:6에 쓰고 조정 비트를 설정합니다. Wire.write(numberL); Wire.endTransmission();}//RDA5807_adrs=0x10;// 순차적 액세스를 위한 I2C 주소 RDA 칩int Readstatus(){ Wire.requestFrom(0x10, 12); for (int i =0; i <6; i++) { status[i] =256 * Wire.read() + Wire.read(); } Wire.endTransmission();}//RDA5807_adrr=0x11;// I2C-Address RDA Chip for random Accessvoid WriteReg(byte reg, unsigned int valor){ Wire.beginTransmission(0x11); Wire.write(reg); Wire.write(값>> 8); Wire.write(valor &0xFF); Wire.endTransmission(); //delay(50);}void RDS_process(uint16_t block1, uint16_t block2, uint16_t block3, uint16_t block4) { rds.processData(block1, block2, block3, block4);}void ClearRDS(){ lcd.print(" ", 0, 22); lcd.print(" ", 0, 30);}// 특별한 이벤트 처리 시간 종료 시간 신호를 듣거나 정확한 시계에서 마지막 시간 초를 볼 때 키 D를 2초 이상 누르십시오. 2. 키 D를 놓아 hh.00.00을 조정합니다. 3. 아터 조정, 만약 당신의 시계가 15분에서 1분으로 늦었다면, 분과 초는 00이 될 것이고 시간은 1만큼 증가할 것입니다. 4. 당신의 시계가 1분에서 15분으로 빨랐다면, 분과 초만 00이 될 것입니다. */ case HOLD:if (key =='D' &&power_state ==1) { adj =1; } 부서지다; 해제된 경우:if (key =='D' &&adj ==1) { DateTime now =rtc.now(); if (now.minute()>=45 &&now.minute() <=59) { rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour() + 1, 0, 0)); } if (now.minute()>=1 &&now.minute() <=15) { rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour( ), 0, 0)); } 조정 =0; } 부서지다; case PRESSED:if (키 =='M' &&power_state ==1) { memdisplay =0; 메뉴++; if (메뉴> 최대메뉴)메뉴 =1; } if (키 =='>' &&power_state ==1) { memdisplay =0; 스위치(메뉴) { 경우 1:if (볼륨 <0) { if (저음 ==0) { WriteReg(0x02, 0xD00D); 볼륨 =0; } if (베이스 ==1) { WriteReg(0x02, 0xC00D); 볼륨 =0; } } 그렇지 않으면 볼륨++; (볼륨> 15) 볼륨 =15인 경우; 부서지다; 사례 2:검색(0); 클리어RDS(); 부서지다; 사례 3:빈도++; if (주파수> 210)주파수 =210; // 주파수 상한 ClearRDS(); 부서지다; 경우 4:if (저음 ==0) { 저음 =1; 쓰기 등록(0x02, 0xD00D); } 부서지다; } } if (키 =='<' &&power_state ==1) { memdisplay =0; 스위치(메뉴) { 케이스 1:볼륨--; if (볼륨 <0) { WriteReg(0x02, 0x800D); //볼륨 =0; } 부서지다; 사례 2:search(1); 클리어RDS(); 부서지다; 사례 3:주파수--; if (주파수 <0)주파수 =0; 클리어RDS(); 부서지다; 경우 4:if (베이스 ==1) { 베이스 =0; 쓰기 등록(0x02, 0xC00D); } 부서지다; } } // LED 켜짐/꺼짐 if (key =='L' &&power_state ==1) { digitalWrite(ledPin, !digitalRead(ledPin)); ledPin_state =디지털 읽기(ledPin); // 점등 또는 소등 LED 상태를 기억합니다. } // "전원"을 켜거나 끕니다(대기 모드) if (key =='P') { digitalWrite(blPin, !digitalRead(blPin)); power_state =디지털 읽기(blPin); if (power_state ==0) { lcd.enableSleep(); 디지털 쓰기(LED 핀, LOW); } 그렇지 않으면 lcd.disableSleep(); 볼륨 =2; 메뉴 =1; } if (키 =='1' &&power_state ==1) { 스위치(memdisplay) { 경우 0:주파수 =mem.readInt(110); 클리어RDS(); 부서지다; 사례 1:mem.writeInt(110, 빈도); 메모리 디스플레이 =0; 부서지다; } } if (키 =='2' &&power_state ==1) { 스위치(memdisplay) { 경우 0:주파수 =mem.readInt(120); 클리어RDS(); 부서지다; 경우 1:mem.writeInt(120, 빈도); 메모리 디스플레이 =0; 부서지다; } } if (키 =='3' &&power_state ==1) { 스위치(memdisplay) { 경우 0:주파수 =mem.readInt(130); 클리어RDS(); 부서지다; 사례 1:mem.writeInt(130, 빈도); 메모리 디스플레이 =0; 부서지다; } } if (키 =='4' &&power_state ==1) { 스위치(memdisplay) { 경우 0:주파수 =mem.readInt(140); 클리어RDS(); 부서지다; 사례 1:mem.writeInt(140, 빈도); 메모리 디스플레이 =0; 부서지다; } } if (키 =='5' &&power_state ==1) { 스위치(memdisplay) { 경우 0:주파수 =mem.readInt(150); 클리어RDS(); 부서지다; 사례 1:mem.writeInt(150, 빈도); 메모리 디스플레이 =0; 부서지다; } } if (키 =='6' &&power_state ==1) { 스위치(memdisplay) { 경우 0:주파수 =mem.readInt(160); 클리어RDS(); 부서지다; 사례 1:mem.writeInt(160, 빈도); 메모리 디스플레이 =0; 부서지다; } } if (키 =='m' &&power_state ==1) { mempress =1; } else { 멤프레스 =0; } if (키 =='나' &&power_state ==1) { dspl =1; } 부서지다; }} 신호 강도 기호C/C++
#if defined(__AVR__) #include #define imagedatatype const uint8_t#elif defined(__PIC32MX__) #define PROGMEM #define imagedatatype const unsigned char#elif defined(__arm__) #define PROGMEM #define imagedatatype const unsigned char#endifimagedatatype signal5[] PROGMEM={0xC1, 0xC2, 0xC4, 0xFF, 0xC4, 0xC2, 0xC1, 0xC0, 0xE0, x10, 0xC0, 0xF0, 0xC0, 0xF0, 0xC0, 00xF8 , }; 이미지 데이터 유형 신호4[] PROGMEM={0xC1, 0xC2, 0xC4, 0xFF, 0xC4, 0xC2, 0xC1, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, // 픽셀 0xF0, 0xC0, 0xF8, 0x0xC };이미지 데이터 유형 신호3[] PROGMEM={0xC1, 0xC2, 0xC4, 0xFF, 0xC4, 0xC2, 0xC1, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, // 0xF0, 0xC0, }픽셀;이미지 데이터 유형 신호2[] PROGMEM={0xC1, 0xC2, 0xC4, 0xFF, 0xC4, 0xC2, 0xC1, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0xC0, 0xC0, 0) 픽셀 imagedatatype signal1[] PROGMEM={0xC1, 0xC2, 0xC4, 0xFF, 0xC4, 0xC2, 0xC1, 0xC0, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, // 0x0010 (16) 픽셀0xC0, };
섹션> 회로도