De basis voor dit project is de code van Rodolfo Broco Manin (RodLophus op GitHub) die een prachtige analoge schaal op 16x2 LCD bevat. Ik heb zijn code aangepast door twee analoge meters toe te voegen voor het lezen van de signaalsterkte en frequentie, de "stereo" LED en de "auto /manual search" LED. Als retro-detail heb ik ook vier geheugentoetsen toegevoegd waarvan de frequenties vooraf zijn gedefinieerd in de code, zodat de radio een volledig antiek uiterlijk krijgt. Audio-uitgangen van de TEA5767 zijn via een stereopotentiometer verbonden met de D-klasse eindversterkermodule met een vermogen van 2x3w, wat voldoende is voor dit doel. Op de versterker zijn twee 2-weg luidsprekers met voldoende vermogen aangesloten. De high-tone speaker is gescheiden van de bass-midrange speaker met 1mf condensator. Analoge meters zijn van een oude defecte radio maar je kunt elke meter gebruiken, en een volledige afwijking van de naald wordt aangepast met trimpotmeters. Het apparaat wordt gevoed door twee lithiumbatterijen in serie via een 7805-stabilisator, dus we hebben een gestabiliseerde 5V-bron.
Je kunt de TEA5767 Arduino-bibliotheek hier vinden. Schakelschema en code worden hieronder gegeven.
Laat me vermelden dat de naald van de frequentiemeter sequentieel wordt bijgewerkt voor elke 1Mhz, wat volgens mij een gevolg is van de bibliotheek, maar als iemand een oplossing vindt voor de soepele beweging van de naald, zou ik het graag accepteren. De ontvangst is uitstekend, vooral voor sterke lokale FM-zenders, terwijl bij zwakkere zenders een stereo/mono-schakelaar nodig is vanwege frequente onderbrekingen van stereo naar mono en vice versa. In de volgende update van de code ben ik van plan om "stereo/mono" en "mute" schakelaars in te voegen.
Het geheel is ingebed in de daarvoor bestemde doos waarop een telescopische antenne is gemonteerd, zodat we een complete FM-stereo-ontvanger hebben met een mooie retro-look.
Code
codeArduino
/*Eenvoudige radiotuner met Arduino Leonardo en de Philips TEA5767-module (Arduino Uno-versie) Opmerkingen:------ De maximale voedingsspanning van de TEA5767 is 5V. Zorg ervoor dat uw Arduino niet meer dan 5V levert. De TEA5767 werkt de signaalniveau-indicator niet bij tijdens het lezen. Het signaalniveau wordt alleen geüpdatet bij het wisselen van zender. Als je een storing krijgt op de encoder of op de drukknop, gebruik dan een snubbernetwerk, zoals dit:Arduino-pin>----+----/\/\/\ /---------> Encoder- of schakelpin | 100 Ohm weerstand ----- ----- 47nF kap | --- GND-aansluitingen:------------ Encoder (met "indrukbare" asschakelaar):Drukknop ---> Arduino pin 2Encoder pin "A" ---> Arduino pin 3Encoder pin "B " ---> Arduino pin 4- LCD:D7 ---> Arduino pin 8D6 ---> Arduino pin 9D5 ---> Arduino pin 10D4 ---> Arduino pin 11RS ---> Arduino pin 13RW ---> GNDE ----> Arduino pin 12VO ---> 2k2 weerstand naar GND (contrast)- TEA5756 module:bovenaanzicht:+-10--9--8--7--6-+| +------+ ++ || | THEE | || || | 5767 | || || +------+ ++ |+--1--2--3--4--5-+1 ----> Arduino SDA2 ----> Arduino SCL3 ----> GND5 ----> +5V6 ----> GND7 ----> Audio out (rechter kanaal)8 ----> Audio out (linker kanaal)10 ---> Antenne Bedankt voor uw interesse. Veel plezier! [email protected]*/#include #include // Download de TEA5767-bibliotheek op https://github.com/andykarpov/TEA5767#include // Encoder pins#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// Custom characters#define SCALE_CLEAR 5 // Radio dial scale#define " STEREO_CHARylized S"#define STEREO_CHAR_T 7 // Gestileerde "T"// Globale statusvlaggen#define ST_AUTO 0 // Automatische modus (omgeschakeld door de drukknop)#define ST_STEREO 1 // Radiomodule heeft een stereopiloot gedetecteerd#define ST_GO_UP 2 // Encoder wordt met de klok mee gedraaid#define ST_GO_DOWN 3 // Encoder wordt tegen de klok in gedraaid#define ST_SEARCH 4 // Radiomodule voert een automatische zoekconst uit int LED =0;int analoogsignaal=0;int analoogschaal=0;int stereoled=0; TEA5767 Radio;float frequentie =88;byte status =0;LiquidCrystal lcd(13, 12, 11, 10, 9, 8);/******************** *********************\ * updateScale() * * Verplaatst de "naald" over de radioschaal *\********* ***********************************/void updateScale() {int lcdBase =(frequentie - 88) * 4; // LCD-kolompixelindex (0 <=lcdBase <=(16 * 5)) if (lcdBase> 79) lcdBase =79; int lcdMajor =lcdBase / 5; // LCD-tekenindex (0 <=lcdMajor <=15) int lcdMinor =lcdBase % 5; // LCD-pixelkolomindex binnen het teken (0 <=lcdMinor <=4) if (lcdMajor> 0) { // De naald van de radiokiezer bevindt zich niet op de meest linkse positie:// reinig het teken aan de linkerkant (om de vorige neddle position) lcd.setCursor(lcdMajor - 1, 0); lcd.write(SCALE_CLEAR); } else lcd.setCursor(lcdMajor, 0); lcd.write(lcdMinor); if(lcdMajor <15) // Niet op de meest rechtse positie:wis het teken aan de rechterkant lcd.write(SCALE_CLEAR);}/************************* ********\ * isrEncoder() * * Interrupts van encoder opvangen *\****************************** **/void isrEncoder() {vertraging(50); // Debouncen (voor waardeloze encoders) if (digitalRead (ENCODER_B) ==HOOG) {bitWrite (status, ST_GO_UP, 1); } else bitWrite(status, ST_GO_DOWN, 1);}/******************************\ * isrSwitch() * * Catch switch? s interrupts *\******************************/void isrSwitch() { delay(50); // Debouncen als (bitRead (status, ST_AUTO)) bitWrite (status, ST_AUTO, 0); else bitWrite(status, ST_AUTO, 1);}/********************\ * Arduino Setup() *\*********** ******/void setup() { Serial.end(); pinMode(button_freq1, INPUT); digitalWrite(button_freq1,LOW); pinMode (button_freq2, INPUT); digitalWrite(button_freq2,LOW); pinMode (button_freq3, INPUT); digitalWrite(button_freq3,LOW); pinMode (button_freq4, INPUT); digitalWrite(button_freq4,LOW); pinMode (LED, UITGANG); pinMode(6,UITGANG); pinMode (7, UITGANG); pinMode (5, UITGANG); int ik; byte naaldChar[8]; // Gestileerde "S" byte stereoChar1 [8] ={0b01111, 0b11000, 0b11011, 0b11101, 0b11110, 0b11000, 0b01111, 0b00000}; lcd.createChar (STEREO_CHAR_S, stereoChar1); // Gestileerde "T" byte stereoChar2 [8] ={0b11110, 0b00011, 0b10111, 0b10111, 0b10111, 0b10111, 0b11110, 0b00000}; lcd.createChar(STEREO_CHAR_T, stereoChar2); // Dial scale background byte scaleChar [8] ={0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00100, 0b10101, 0b10101}; lcd.createChar (SCALE_CLEAR, scaleChar); // Maak een aangepast teken om alle (5) mogelijke naaldposities weer te geven 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.wissen(); // Teken de achtergrond van de schaal voor (i =0; i <16; i++) lcd.write (SCALE_CLEAR); pinMode (ENCODER_SW, INPUT); digitalWrite (ENCODER_SW, HOOG); pinMode (ENCODER_A, INPUT); digitalWrite (ENCODER_A, HOOG); pinMode (ENCODER_B, INPUT); digitalWrite (ENCODER_B, HOOG); attachInterrupt(0, isrSwitch, RISING); attachInterrupt(1, isrEncoder, RISING); // Initialiseer de radiomodule Wire.begin(); Radio.init(); Radio.set_frequency(frequentie);}/******************\ * Arduino Loop() *\*************** ***/void loop() { unsigned char buf[5]; int-stereo; int signaalNiveau; int zoekenRichting; int ik; ik=0; // Update de automatische / handmatige indicator lcd.setCursor (12, 1); lcd.write(bitRead(status, ST_AUTO) ? 'A':'M'); if bitRead (status, ST_AUTO) // Auto/manual LED {digitalWrite (LED, LOW); } else { digitalWrite (LED, HOOG); } if (Radio.read_status(buf) ==1) { // Get radio data frequency =floor(Radio.frequency_available(buf) / 100000 + .5)/10; stereo =Radio.stereo(buf); // 0 <=Radio.signal_level <=15 signalLevel =(Radio.signal_level (buf) * 100) / 15; analoogsignaal=kaart(signaalniveau,0,100,0,255); analogscale=kaart(frequentie,88,114,0,255); stereoled=kaart(stereo,0.7,1,0,255); analogWrite (5,analoogsignaal); // Signaalmeter analoogWrite (6,analoge schaal); //frequentiemeter analoogWrite (7,stereoled); //stereo LED // Update de radio dial updateScale(); // Signaalniveau-indicator lcd.setCursor (0, 1); lcd.schrijven (183); // Japans karakter dat eruitziet als een antenne :) if(signalLevel <100) lcd.write(' '); lcd.print(signaalniveau); lcd.write('%'); // Frequentie-indicator lcd.setCursor (6, 1); if(frequentie <100) lcd.write(' '); lcd.print (frequentie, 1); // Mono / stereo-indicator lcd.setCursor (14, 1); if(stereo){ lcd.write(STEREO_CHAR_S); lcd.write(STEREO_CHAR_T); } else lcd.print(" "); } if(bitRead(status, ST_SEARCH)) { // Voert de radio een automatische zoekopdracht uit? if(Radio.process_search(buf, searchDirection) ==1) { bitWrite(status, ST_SEARCH, 0); } } if(digitalRead(button_freq2)==HIGH){ //"geheugen"-knoppen if(frequentie> 94,8) { frequency=94,8; Radio.set_frequentie (frequentie); bitWrite(status, ST_GO_DOWN, 0); } anders { frequentie=94,8; Radio.set_frequentie (frequentie); bitWrite(status, ST_GO_UP, 0); } precrtajScale(); }if(digitalRead(button_freq1)==HIGH){ if(frequentie> 92) { frequency=92; Radio.set_frequentie (frequentie); bitWrite(status, ST_GO_DOWN, 0); } anders { frequentie=92; Radio.set_frequentie (frequentie); bitWrite(status, ST_GO_UP, 0); } precrtajScale();}if(digitalRead(button_freq3)==HIGH){ if(frequentie> 97) { frequency=97; Radio.set_frequentie (frequentie); bitWrite(status, ST_GO_DOWN, 0); } anders { frequentie=97; Radio.set_frequentie (frequentie); bitWrite(status, ST_GO_UP, 0); } precrtajScale(); }if(digitalRead(button_freq4)==HIGH){ if(frequentie> 101.2) { frequency=101,2; Radio.set_frequentie (frequentie); bitWrite(status, ST_GO_DOWN, 0); } anders { frequentie=101,2; Radio.set_frequentie (frequentie); bitWrite(status, ST_GO_UP, 0); } precrtajScale();} // Encoder wordt rechtsom gedraaid (+) if(bitRead(status, ST_GO_UP)) { if(bitRead(status, ST_AUTO) &&!bitRead(status, ST_SEARCH)) { // Automatische zoekmodus (alleen verwerkt als de radio momenteel geen zoekopdracht uitvoert) bitWrite(status, ST_SEARCH, 1); searchDirection =TEA5767_SEARCH_DIR_UP; Radio.zoek_up(buf); vertraging (50); } else { // Handmatige afstemmingsmodus if (frequentie <108) { frequentie +=0.1; Radio.set_frequentie (frequentie); } } bitWrite(status, ST_GO_UP, 0); } // Encoder wordt tegen de klok in gedraaid (-) if(bitRead(status, ST_GO_DOWN)) { if(bitRead(status, ST_AUTO) &&!bitRead(status, ST_SEARCH)) { // Automatische zoekmodus (alleen verwerkt als de radio is voert momenteel geen zoekopdracht uit) bitWrite(status, ST_SEARCH, 1); searchDirection =TEA5767_SEARCH_DIR_DOWN; Radio.zoek_down(buf); vertraging (50); } else { // Handmatige afstemmingsmodus if(frequentie> 88) {frequentie -=0.1; Radio.set_frequentie (frequentie); } } bitWrite (status, ST_GO_DOWN, 0); }}void precrtajScale() { int i; lcd.wissen(); for(i =0; i <16; i++) lcd.write(SCALE_CLEAR);}
Schema's