이 프로젝트 정보
이 프로젝트의 기반은 16x2 LCD에 아름다운 아날로그 스케일이 포함된 Rodolfo Broco Manin(GitHub의 RodLophus) 코드입니다. 나는 신호 강도와 주파수를 읽기 위한 두 개의 아날로그 미터, "스테레오" LED 및 "자동/수동 검색" LED를 추가하여 그의 코드를 수정했습니다. 또한 레트로 디테일로 코드에 주파수가 미리 정의된 4개의 메모리 키를 추가하여 라디오가 완전히 앤티크한 느낌을 줍니다. 스테레오 전위차계를 통해 TEA5767의 오디오 출력은 이 목적에 충분한 2x3w 전력으로 D 클래스 전력 증폭기 모듈에 연결됩니다. 앰프에는 적절한 출력을 가진 2개의 2-way 스피커가 연결되어 있습니다. 고음 스피커는 1mf 커패시터로 중저음 스피커와 분리됩니다. Аnalog 미터는 결함이 있는 오래된 라디오에서 가져온 것이지만 모든 미터를 사용할 수 있으며 바늘의 전체 편차는 트리머 전위차계로 조정됩니다. 이 장치는 7805 스태빌라이저를 통해 직렬로 연결된 두 개의 리튬 배터리로 구동되므로 5V 소스를 안정화했습니다.
TEA5767 Arduino 라이브러리는 여기에서 찾을 수 있습니다. 회로도와 코드는 아래와 같습니다.
주파수 측정기 바늘이 1Mhz마다 순차적으로 업데이트된다는 점을 말씀드리자면, 라이브러리의 결과라고 생각합니다만, 바늘이 부드럽게 움직일 수 있는 방법을 누군가가 찾아준다면 흔쾌히 수락하겠습니다. 수신은 특히 강한 지역 FM 방송국에 대해 우수하지만 약한 방송국에서는 스테레오에서 모노로 또는 그 반대로 자주 중단되기 때문에 스테레오/모노 스위치가 필요합니다. 다음 코드 업데이트에서는 "스테레오/모노" 및 "음소거" 스위치를 삽입할 계획입니다.
전체 어셈블리는 텔레스코픽 안테나가 장착된 해당 상자에 포함되어 있으므로 멋진 복고풍 모양의 완전한 FM 스테레오 수신기가 있습니다.
섹션> <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드"> 코드
<울> 코드
코드Arduino
/*Arduino Leonardo 및 Philips TEA5767 모듈을 사용하는 간단한 라디오 튜너(Arduino Uno 버전) 참고:------ TEA5767 최대 공급 전압은 5V입니다. Arduino가 5V 이상을 소싱하지 않는지 확인하십시오. TEA5767은 읽을 때 신호 레벨 표시기를 업데이트하지 않습니다. 신호 레벨은 스테이션 변경 시에만 업데이트됩니다. 인코더 또는 푸시 버튼에 일부 결함이 있는 경우 다음과 같은 스너버 네트워크를 사용하십시오.Arduino 핀>----+----/\/\/\ /---------> 인코더 또는 스위치 핀 | 100Ohms 저항 ------ ------ 47nF 캡 | --- GNDConnections:------------ 인코더("푸시 가능한" 샤프트 스위치 포함):푸시 버튼 ---> Arduino 핀 2Encoder 핀 "A" ---> Arduino 핀 3Encoder 핀 "B " ---> Arduino 핀 4- LCD:D7 ---> Arduino 핀 8D6 ---> Arduino 핀 9D5 ---> Arduino 핀 10D4 ---> Arduino 핀 11RS ---> Arduino 핀 13RW ---> GNDE ----> Arduino 핀 12VO ---> GND에 대한 2k2 저항(대비)- TEA5756 모듈:평면도:+-10--9--8--7--6-+| +------+ ++ || | 차 | || || | 5767 | || || +------+ ++ |+--1--2--3--4--5-+1 ----> Arduino SDA2 ----> Arduino SCL3 ----> GND5 ----> +5V6 ----> GND7 ----> 오디오 출력(오른쪽 채널)8 ----> 오디오 출력(왼쪽 채널)10 ---> 안테나 관심 감사합니다.재미있게! [email protected]*/#include #include // https://github.com/andykarpov/TEA5767#include // 인코더에서 TEA5767 라이브러리 받기 " //pin#define ENCODER_SW 2#define ENCODER_A 3#define ENCODER_B 4#define button_freq1 A0#define button_freq2 A1#define button_freq3 A2#define button_freq4 A3// 사용자 정의 문자#define SCALE_CLEAR 5 // STEREO 다이얼 scale#define S#define STEREO_CHAR_T 7 // Stylized "T"// 글로벌 상태 플래그#define ST_AUTO 0 // 자동 모드(푸시 버튼으로 토글됨)#define ST_STEREO 1 // 라디오 모듈이 스테레오 파일럿을 감지했습니다.#define ST_GO_UP 2 // 인코더가 시계 방향으로 돌고 있음#define ST_GO_DOWN 3 // 인코더가 시계 반대 방향으로 돌고 있음#define ST_SEARCH 4 // 라디오 모듈이 자동 searchconst를 수행 중입니다. int LED =0;int analogsignal=0;int analogscale=0;int stereoled=0; TEA5767 라디오; 부동 주파수 =88; 바이트 상태 =0;LiquidCrystal lcd(13, 12, 11, 10, 9, 8);/******************** ***********************\ * updateScale() * * 무선 저울 위로 "바늘"을 이동합니다. *\********* **********************************/void updateScale() { int lcdBase =(주파수 - 88) * 4; // LCD 컬럼 픽셀 인덱스 (0 <=lcdBase <=(16 * 5)) if(lcdBase> 79) lcdBase =79; 정수 lcdMajor =lcdBase / 5; // LCD 문자 인덱스 (0 <=lcdMajor <=15) int lcdMinor =lcdBase % 5; // 문자 내의 LCD 픽셀 열 인덱스 (0 <=lcdMinor <=4) if(lcdMajor> 0) { // 라디오 다이얼 바늘이 맨 왼쪽 위치에 있지 않습니다. // 왼쪽에 있는 문자를 청소합니다(이전 삭제 네들 위치) lcd.setCursor(lcdMajor - 1, 0); lcd.write(SCALE_CLEAR); } 그렇지 않으면 lcd.setCursor(lcdMajor, 0); lcd.write(lcdMinor); if(lcdMajor <15) // 맨 오른쪽 위치가 아님:오른쪽 문자 지우기 lcd.write(SCALE_CLEAR);}/************************ ********\ * isrEncoder() * * 엔코더 캐치? 인터럽트 *\**************************** **/ 무효 isrEncoder() { 지연(50); // 디바운싱(엉성한 인코더용) if(digitalRead(ENCODER_B) ==HIGH){ bitWrite(status, ST_GO_UP, 1); } else bitWrite(status, ST_GO_DOWN, 1);}/****************************\ * isrSwitch() * * 캐치 스위치? 인터럽트 *\********************************/void isrSwitch() { delay(50); // 디바운싱 if(bitRead(status, ST_AUTO)) bitWrite(status, ST_AUTO, 0); else bitWrite(상태, ST_AUTO, 1);}/**********************\ * 아두이노 설정() *\************* ********/void setup() { Serial.end(); 핀모드(버튼 주파수1, 입력); digitalWrite(button_freq1,LOW); 핀모드(버튼 주파수2, 입력); digitalWrite(button_freq2,LOW); 핀모드(버튼_주파수3, 입력); digitalWrite(button_freq3,LOW); 핀모드(버튼_주파수4, 입력); digitalWrite(button_freq4,LOW); 핀모드(LED, 출력); 핀모드(6, 출력); 핀모드(7, 출력); 핀모드(5, 출력); 정수 나; 바이트 바늘 문자[8]; // 양식화된 "S" 바이트 stereoChar1[8] ={ 0b01111, 0b11000, 0b11011, 0b11101, 0b11110, 0b11000, 0b01111, 0b00000 }; lcd.createChar(STEREO_CHAR_S, 스테레오Char1); // 스타일화된 "T" 바이트 stereoChar2[8] ={ 0b11110, 0b00011, 0b10111, 0b10111, 0b10111, 0b10111, 0b11110, 0b00000 }; lcd.createChar(STEREO_CHAR_T, stereoChar2); // 다이얼 스케일 배경 바이트 scaleChar[8] ={ 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00100, 0b10101, 0b10101 }; lcd.createChar(SCALE_CLEAR, scaleChar); // 가능한 모든 (5) 개의 바늘 위치를 나타내는 사용자 정의 문자 생성 for(int j =0; j <5; j++) { for(i =0; i <8; i++) needleChar[i] =scaleChar[i ] | (0b10000>> j); lcd.createChar(j, needleChar); } lcd.begin(16, 2); lcd.clear(); // 다이얼 눈금의 배경을 그립니다. for(i =0; i <16; i++) lcd.write(SCALE_CLEAR); 핀모드(ENCODER_SW, 입력); 디지털 쓰기(ENCODER_SW, HIGH); 핀모드(ENCODER_A, 입력); 디지털 쓰기(ENCODER_A, 높음); 핀모드(ENCODER_B, 입력); 디지털 쓰기(ENCODER_B, 높음); attachInterrupt(0, isrSwitch, 상승); attachInterrupt(1, isrEncoder, RISING); // 라디오 모듈 초기화 Wire.begin(); 라디오.초기화(); Radio.set_frequency(주파수);}/******************\ * Arduino 루프() *\****************** ***/void 루프() { 부호 없는 char buf[5]; 인트 스테레오; 정수 신호 레벨; int searchDirection; 정수 나; 나는 =0; // 자동/수동 표시기 업데이트 lcd.setCursor(12, 1); lcd.write(bitRead(상태, ST_AUTO) ? 'A' :'M'); if bitRead(status, ST_AUTO) // 자동/수동 LED { digitalWrite(LED, LOW); } else { 디지털 쓰기(LED, 높음); } if (Radio.read_status(buf) ==1) { // 라디오 데이터 얻기 주파수 =floor(Radio.frequency_available(buf) / 100000 + .5) / 10; 스테레오 =Radio.stereo(buf); // 0 <=Radio.signal_level <=15 signalLevel =(Radio.signal_level(buf) * 100) / 15; analogsignal=map(signalLevel,0,100,0,255); analogscale=map(주파수,88,114,0,255); 입체=지도(스테레오,0.7,1,0,255); analogWrite (5, 아날로그 신호); // 신호 미터 analogWrite(6,analogscale); //주파수 측정기 analogWrite (7, 스테레오); //스테레오 LED // 라디오 다이얼 업데이트 updateScale(); // 신호 레벨 표시기 lcd.setCursor(0, 1); lcd.write(183); // 안테나처럼 생긴 일본어 :) if(signalLevel <100) lcd.write(' '); lcd.print(signalLevel); lcd.write('%'); // 주파수 표시기 lcd.setCursor(6, 1); if(주파수 <100) lcd.write(' '); lcd.print(주파수, 1); // 모노 / 스테레오 표시기 lcd.setCursor(14, 1); if(스테레오){ lcd.write(STEREO_CHAR_S); lcd.write(STEREO_CHAR_T); } 그렇지 않으면 lcd.print(" "); } if(bitRead(status, ST_SEARCH)) { // 라디오가 자동 검색을 수행합니까? if(Radio.process_search(buf, searchDirection) ==1) { bitWrite(상태, ST_SEARCH, 0); } } if(digitalRead(button_freq2)==HIGH){ //"메모리" 버튼 if(주파수> 94.8) { 주파수=94.8; Radio.set_frequency(주파수); bitWrite(상태, ST_GO_DOWN, 0); } else { 빈도=94.8; Radio.set_frequency(주파수); bitWrite(상태, ST_GO_UP, 0); } precrtajScale(); }if(digitalRead(button_freq1)==HIGH){ if(주파수> 92) { 주파수=92; Radio.set_frequency(주파수); bitWrite(상태, ST_GO_DOWN, 0); } else { 빈도=92; Radio.set_frequency(주파수); bitWrite(상태, ST_GO_UP, 0); } precrtajScale();}if(digitalRead(button_freq3)==HIGH){ if(주파수> 97) { 주파수=97; Radio.set_frequency(주파수); bitWrite(상태, ST_GO_DOWN, 0); } else { 빈도=97; Radio.set_frequency(주파수); bitWrite(상태, ST_GO_UP, 0); } precrtajScale(); }if(digitalRead(button_freq4)==HIGH){ if(주파수> 101.2) { 주파수=101.2; Radio.set_frequency(주파수); bitWrite(상태, ST_GO_DOWN, 0); } else { 빈도=101.2; Radio.set_frequency(주파수); bitWrite(상태, ST_GO_UP, 0); } precrtajScale();} // 인코더를 시계 방향으로 돌림(+) if(bitRead(status, ST_GO_UP)) { if(bitRead(status, ST_AUTO) &&!bitRead(status, ST_SEARCH)) { // 자동 검색 모드(only 라디오가 현재 검색을 수행하지 않는 경우 처리됨) bitWrite(status, ST_SEARCH, 1); searchDirection =TEA5767_SEARCH_DIR_UP; Radio.search_up(buf); 지연(50); } else { // 수동 튜닝 모드 if(frequency <108) { frequency +=0.1; Radio.set_frequency(주파수); } } bitWrite(상태, ST_GO_UP, 0); } // 인코더를 시계 반대 방향으로 돌림(-) if(bitRead(status, ST_GO_DOWN)) { if(bitRead(status, ST_AUTO) &&!bitRead(status, ST_SEARCH)) { // 자동 검색 모드(무선이 다음과 같을 때만 처리됨 현재 검색을 수행하지 않음) bitWrite(status, ST_SEARCH, 1); searchDirection =TEA5767_SEARCH_DIR_DOWN; Radio.search_down(buf); 지연(50); } else { // 수동 튜닝 모드 if(frequency> 88) { frequency -=0.1; Radio.set_frequency(주파수); } } bitWrite(상태, ST_GO_DOWN, 0); }} 무효 precrtajScale() { int i; lcd.clear(); for(i =0; i <16; i++) lcd.write(SCALE_CLEAR);}
섹션> 회로도