W kontekście tego szaleństwa, które nas otacza od dni 10-ciu, szaleństwem nie mniejszym wydaje się robienie łazienkowego radia. Ale muszę coś robić, żeby nie zwariować od wiadomości pokazujących w jak czarnej dziurze jesteśmy. Mogę tylko dodać: wspierajcie Fundację Ad Arma – to są dobrzy i rozsądni ludzie.
Projekt ten zaczął się już 4 lata temu ale jakoś się nie rozwinął. Były to próby z zupełnie innym, niż obecny, modułem. Radio działało, miało wyświetlacz (od Nokii) potencjometry i wzmacniacz ale sam moduł miał jakąś wadę. Kopałem się z tym koniem tak długo, że skończyła mi się cierpliwość.
Resztki wyglądają tak:

Nowy moduł to TEA5767 z gniazdami typu jack dla anteny i słuchawek. Wyjście słuchawkowe wykorzystam jako sygnał do dodatkowego wzmacniacza bo głośnika, wbudowany nie uciągnie.
Zalążek wygląda tak:

W Arduino IDE doinstalowałem bibliotekę o nazwie „Radio”, strona biblioteki jest pod tym adresem: http://www.mathertel.de/Arduino/RadioLibrary.aspx.
Używam Arduino UNO ale im bliżej końca tym bardziej będę chciał użyć jakiegoś klona Nano, mam ATmega328 CH340, z tym że boję się czy wystarczy pamięci do sprawnego działania. Ostatnim razem miałem, jak pisałem już wyżej, kłopoty i coś mi się zaczyna przypominać, że jechał już na oparach jeśli chodzi o pamięć.
Głośnik mam sufitowy, marki Blow, o nast. specyfikacji:
Średnica | 4 cale |
Moc maksymalna | 15 W |
Impedancja | 8 Ohm |
Cewka | 0,75″ ASV |
Magnes | 60x24x8 |
Zakres częstotliwości | 104Hz – 15kHz |
Czułość | 87dB +/- 2dB |
Myślę nad wzmacniaczem… moje typy, totalnie na czuja i chyba przesadzone:
https://mageek.com.pl/audio-wzmacniacze/244-modul-wzmacniacz-audio-pam88610.html
Do sterowania mam zamiar użyć panelu dotykowego:
https://www.artronic.eu/pl/p/LCD-RTP-128064A-goldpin4/1043
Wydrukować pod spód wkładkę z narysowanymi przyciskami bo nie znalazłem wodoodpornego panelu.
A’propos wody to myślę jak zabezpieczyć całość. Ludzie proponują takie specyfiki:
https://www.f4p-products.com/products/4319079-2-x-150ml-bottles-of-magic-gel
ewentualnie pudełko:
https://www.adafruit.com/product/341
Aha, a kod? Zalążek wzięty z przykładu załączonego do blblioteki „Radio”:
///
/// \file SerialRadio.ino
/// \brief Radio implementation using the Serial communication.
///
/// \author Matthias Hertel, http://www.mathertel.de
/// \copyright Copyright (c) 2014 by Matthias Hertel.\n
/// This work is licensed under a BSD style license.\n
/// See http://www.mathertel.de/Arduino/RadioLibrary.aspx
///
/// \details
/// This is a full function radio implementation that uses a LCD display to show the current station information.\n
/// It can be used with various chips after adjusting the radio object definition.\n
/// Open the Serial console with 57600 baud to see current radio information and change various settings.
///
/// Wiring
/// ------
/// The necessary wiring of the various chips are described in the Testxxx example sketches.
/// The boards have to be connected by using the following connections:
///
/// Arduino port | TEA5767 z portami dla anteny i sluchawek
/// :----------: | :-----------:
/// GND (black) | GND
/// 3.3V (red) | -
/// 5V (red) | VCC
/// A5 (yellow) | SLC (SLCK)
/// A4 (blue) | SDA (SDIO)
/// D2 | -
///
/// UWAGA RDS NIE DZIALA!
///
/// More documentation and source code is available
/// at http://www.mathertel.de/Arduino
///
/// History:
/// --------
/// * 05.08.2014 created.
/// * 04.10.2014 working.
#include <Wire.h>
#include <radio.h>
#include <TEA5767.h>
#include <RDSParser.h>
// Define some stations available at your locations here:
// 89.40 MHz as 8940
RADIO_FREQ preset[] = {
8780, // Wnet
8840, // Pogoda
8900, // Maryja
8980, // Supernova
9060, // RMF FM
9200, // Polskie Radio 24
9240, // Jedynka
9330, // Eska
9710, // Kampus
9770, // Tok FM
9880, // Trojka
10110, // Zlote Przeboje
10150, // ChilliZet
10370, // Rock Radio
10680 // Antyradio
};
int i_sidx = 0; ///< Start at Station with index=0
/// The radio object has to be defined by using the class corresponding to the used chip.
/// by uncommenting the right radio object definition.
TEA5767 radio; ///< Create an instance of a TEA5767 chip radio.
/// get a RDS parser
RDSParser rds;
/// State definition for this radio implementation.
enum RADIO_STATE {
STATE_PARSECOMMAND, ///< waiting for a new command character.
STATE_PARSEINT, ///< waiting for digits for the parameter.
STATE_EXEC ///< executing the command.
};
RADIO_STATE state; ///< The state variable is used for parsing input characters.
// - - - - - - - - - - - - - - - - - - - - - - - - - -
/// Update the Frequency on the LCD display.
void DisplayFrequency(RADIO_FREQ f)
{
char s[12];
radio.formatFrequency(s, sizeof(s));
Serial.print("FREQ:"); Serial.println(s);
} // DisplayFrequency()
/// Update the ServiceName text on the LCD display.
void DisplayServiceName(char *name)
{
Serial.print("RDS:");
Serial.println(name);
} // DisplayServiceName()
// - - - - - - - - - - - - - - - - - - - - - - - - - -
void RDS_process(uint16_t block1, uint16_t block2, uint16_t block3, uint16_t block4) {
rds.processData(block1, block2, block3, block4);
}
/// Execute a command identified by a character and an optional number.
/// See the "?" command for available commands.
/// \param cmd The command character.
/// \param value An optional parameter for the command.
void runSerialCommand(char cmd, int16_t value)
{
if (cmd == '?') {
Serial.println();
Serial.println("? Help");
Serial.println("+ increase volume DON'T WORK");
Serial.println("- decrease volume DON'T WORK");
Serial.println("> next preset");
Serial.println("< previous preset");
Serial.println(". scan up DON'T WORK");
Serial.println(", scan down DON'T WORK");
Serial.println("fnnnnn: direct frequency input");
Serial.println("i station status");
Serial.println("s mono/stereo mode");
Serial.println("b bass boost DON'T WORK");
Serial.println("u mute/unmute");
}
// ----- control the volume and audio output -----
else if (cmd == '+') {
// increase volume
int v = radio.getVolume();
if (v < 15) radio.setVolume(++v);
Serial.println();
Serial.print("Increasing volume:"); Serial.println(v);
}
else if (cmd == '-') {
// decrease volume
int v = radio.getVolume();
if (v > 0) radio.setVolume(--v);
Serial.println();
Serial.print("Decreasing volume:"); Serial.println(v);
}
else if (cmd == 'u') {
// toggle mute mode
radio.setMute(!radio.getMute());
}
// toggle stereo mode
else if (cmd == 's') {
radio.setMono(!radio.getMono());
}
// toggle bass boost
else if (cmd == 'b') {
radio.setBassBoost(!radio.getBassBoost());
}
// ----- control the frequency -----
else if (cmd == '>') {
// next preset
if (i_sidx < (sizeof(preset) / sizeof(RADIO_FREQ)) - 1) {
i_sidx++; radio.setFrequency(preset[i_sidx]);
} // if
} else if (cmd == '<') {
// previous preset
if (i_sidx > 0) {
i_sidx--;
radio.setFrequency(preset[i_sidx]);
} // if
} else if (cmd == 'f') {
radio.setFrequency(value);
}
else if (cmd == '.') {
radio.seekUp(false);
} else if (cmd == ':') {
radio.seekUp(true);
} else if (cmd == ',') {
radio.seekDown(false);
} else if (cmd == ';') {
radio.seekDown(true);
}
// not in help:
else if (cmd == '!') {
if (value == 0) radio.term();
if (value == 1) radio.init();
} else if (cmd == 'i') {
char s[12];
radio.formatFrequency(s, sizeof(s));
Serial.print("Station:"); Serial.println(s);
Serial.print("Radio:"); radio.debugRadioInfo();
Serial.print("Audio:"); radio.debugAudioInfo();
} // info
else if (cmd == 'x') {
radio.debugStatus(); // print chip specific data.
}
} // runSerialCommand()
/// Setup a FM only radio configuration with I/O for commands and debugging on the Serial port.
void setup() {
// open the Serial port
Serial.begin(57600);
Serial.print("Radio...");
delay(500);
// Initialize the Radio
radio.init();
// Enable information to the Serial port
radio.debugEnable();
radio.setBandFrequency(RADIO_BAND_FM, preset[i_sidx]); // 5. preset.
// delay(100);
radio.setMono(false);
radio.setMute(false);
// radio._wireDebug();
radio.setVolume(8);
Serial.write('>');
state = STATE_PARSECOMMAND;
// setup the information chain for RDS data.
radio.attachReceiveRDS(RDS_process);
rds.attachServicenNameCallback(DisplayServiceName);
runSerialCommand('?', 0);
} // Setup
/// Constantly check for serial input commands and trigger command execution.
void loop() {
int newPos;
unsigned long now = millis();
static unsigned long nextFreqTime = 0;
static unsigned long nextRadioInfoTime = 0;
// some internal static values for parsing the input
static char command;
static int16_t value;
static RADIO_FREQ lastf = 0;
RADIO_FREQ f = 0;
char c;
if (Serial.available() > 0) {
// read the next char from input.
c = Serial.peek();
if ((state == STATE_PARSECOMMAND) && (c < 0x20)) {
// ignore unprintable chars
Serial.read();
} else if (state == STATE_PARSECOMMAND) {
// read a command.
command = Serial.read();
state = STATE_PARSEINT;
} else if (state == STATE_PARSEINT) {
if ((c >= '0') && (c <= '9')) {
// build up the value.
c = Serial.read();
value = (value * 10) + (c - '0');
} else {
// not a value -> execute
runSerialCommand(command, value);
command = ' ';
state = STATE_PARSECOMMAND;
value = 0;
} // if
} // if
} // if
// check for RDS data
radio.checkRDS();
// update the display from time to time
if (now > nextFreqTime) {
f = radio.getFrequency();
if (f != lastf) {
// print current tuned frequency
DisplayFrequency(f);
lastf = f;
} // if
nextFreqTime = now + 400;
} // if
} // loop
// End.