Rádio FM à Prova d'Água para Chuveiro com Arduino Nano, RDA5807, LCD Nokia e PAM8403
Componentes e Materiais
| Componente | Quantidade |
|---|---|
| Arduino Nano R3 | 1 |
| Módulo de rádio FM RDA5807 (RDA Microelectronics) | 1 |
| LCD Nokia 5110 3V-5V | 1 |
| Módulo RTC Tiny (DS1307 + EEPROM 24c32) | 1 |
| Amplificador classe D PAM8403 (2×3W) | 1 |
| Conversor DC-DC Step Down LM2596 (Texas Instruments) | 1 |
| Bateria recarregável LIR2032 3,6V | 1 |
| Resistor 100 Ω | 1 |
| Resistor 1 kΩ | 1 |
| Resistor 10 kΩ | 6 |
| Resistor 100 kΩ | 1 |
| MOSFET de potência IRLZ44 (Infineon) | 1 |
| Alto-falantes PEIYING PY1010C 60W 4Ω | 1 |
| Fonte 12V 3A (recuperada) | 1 |
| Capacitores 2200 µF 25V | 2 |
| Capacitor 100 µF | 1 |
| Lâmpadas LED 3W para substituir halógenos G4 10W | 1 |
Sobre o Projeto
Há alguns anos, comprei uma cabine de chuveiro chinesa com sistema de controle TR028 com rádio. Infelizmente, o sistema morreu completamente. Ninguém conseguiu repará-lo, então comprei outro rádio de chuveiro mais barato. Morreu após cerca de um ano.
Minha família estava acostumada a ter rádio na cabine, então comecei a estudar como esses rádios eram feitos. Dentro do sistema TR028 encontrei um estranho módulo TEA5767. Pesquisas mostraram que é um pequeno módulo de rádio FM barato. Nos resultados, encontrei outro módulo interessante: RDA5807. Muito similar ao TEA5767, mas com RDS, controle de volume e bass boost. Decidi usar o RDA5807 no meu novo projeto.
Pesquisei na internet e encontrei vários projetos usando o RDA5807, mas nenhum atendia exatamente à minha visão.
Minha Visão
- Dispositivo com tela sensível ao toque para garantir construção à prova d'água (usei gabinete com painel touch do TR028 morto).
- Rádio FM
- Vários presets de estações favoritas
- Controle de volume
- Busca automática de estações
- Possibilidade de memorizar estação encontrada
- Relógio para ver a hora atual
- Liga/Desliga
- Controle de luz
- Exibição de informações menores como temperatura interna da cabine, RDS
No Aliexpress comprei RDA5807, Tiny RTC com EEPROM 32kb, PAM8403, LCD Nokia 5110, módulos LM2596 por menos de 10€ e comecei os experimentos.
O que Consegui
- Rádio FM com RDS de 2 linhas (!)
- 6 presets para estações favoritas
- Sintonia automática ou manual
- Possibilidade de armazenar estação favorita em um dos 6 presets
- Controle de volume e bass boost
- Controle de luzes da cabine de chuveiro
- Relógio e calendário
- RSSI (indicador de intensidade do sinal)
- Indicador de modo estéreo
- Liga/Desliga
Como Funciona
- O rádio não liga automaticamente ao conectar a fonte. Isso evita que toque se a energia não for estável ou houver queda. Para ligar pela primeira vez, conecte a fonte e após alguns segundos pressione a tecla de power. O rádio tocará a última estação com volume no nível 03. Modo de operação: controle de VOLUME. Para desligar, pressione a tecla de power. O dispositivo desliga LCD, backlight, amplificador e LED/lâmpada halógena.
- Para buscar estação, escolha modo Auto ou Manual pressionando o botão "Mod". Com "<" ou ">", o rádio busca diminuindo ou aumentando a frequência. Para armazenar, pressione "Mem" e terá 4 segundos para escolher um dos 6 presets.
- Para ver a data atual, pressione a tecla I (info). A data aparece por 4 segundos. Esta parte pode ser otimizada pois usa delay().
- Para ajustar o relógio, pressione e segure a tecla D por pelo menos 2 segundos quando ouvir sinais de fim de hora ou ver os últimos segundos em algum relógio preciso. Solte a tecla D para ajustar para hh.00.00. Se o relógio estava adiantado de 1 a 15 minutos, apenas minutos e segundos serão zerados. Se atrasado de 15 a 1 minutos, minutos e segundos zeram e horas aumentam em 1.
O que Mudaria
- O ressonador do módulo RTC para melhor precisão (mas o ajuste de relógio resolve).
- O LCD 5110 por um maior e mais brilhante, talvez 1,8" ou 2,0" colorido, pois às vezes é difícil ler no Nokia 5110.
- O amplificador PAM8403 por PAM8610 (2×15W) ou TDA7297.
Conclusão
Estou feliz com o funcionamento do projeto. Nenhum problema observado após 1 mês de uso, exceto a precisão do relógio.
Não sou programador, então o código pode ser otimizado. Minha experiência em C/C++ é de cerca de um ano, autodidata. É meu primeiro projeto útil com Arduino e o primeiro que compartilho. Por favor, entendam e perdoem possíveis erros e meu inglês ruim.
Se tiverem dúvidas, não hesitem em perguntar nos comentários ou PM.
Atualização 1: Pequenas atualizações de hardware e software. Hardware: fusível 2A na linha 12V por segurança. Software: adicionada linha 586 menu = 1; para restaurar modo VOLUME ao pressionar power.
Atualização 2: Infelizmente o LCD do meu rádio está morrendo. Busco alternativa barata ao Nokia 5110. Não vou instalar outro 5110 porque é pequeno e difícil de ler. Vou experimentar com LCD TFT 1,8". Vantagens: maior, mais brilhante, melhor resolução. Desvantagens: consumirá mais recursos que são críticos. Sugestões são bem-vindas.
Código
Sketch do Projeto
/////////////////////////////////////////////////////////////////
// Arduino based shower FM Radio Project
// Arduino NANO, RDA5807M, RTC, EEPROM, LCD5110, Thermistor
/////////////////////////////////////////////////////////////////
#include <LCD5110_Graph.h>
#include <AT24CX.h>
#include <Wire.h>
#include <RDSParser.h>
#include <radio.h>
#include <RTClib.h>
#include <RDA5807M.h>
#include <Keypad.h>
#define MAXmenu 4
#define ledPin 13
#define blPin 7
char keys[7][2] = {
{'L', 'P'}, // LED, POWER
{'I', 'D'}, // INFO, DISPLAY
{'1', '2'}, // presets
{'3', '4'}, // from 1
{'5', '6'}, // to 6
{'M', 'm'}, // MODE, MEM
{'<', '>'} // down, up
};
byte rowPins[7] = {11, 12, 10, 17, 9, 16, 8};
byte colPins[2] = {15, 14};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, 7, 2);
boolean bass = 0, dspl = 0, memdisplay = 0, mempress = 0, adj = 0;
boolean ledPin_state, power_state;
int menu;
int volume, volumeOld = 5;
int frequency, frequencyOld;
int txtl = 0, temparray = 0;
int samples[5];
unsigned int status[6];
unsigned long timeprevious = 0, timeprev = 0;
AT24CX mem;
RTC_DS1307 rtc;
LCD5110 lcd(6, 5, 4, 2, 3);
RDA5807M radio;
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[];
void setup() {
analogReference(EXTERNAL);
Serial.begin(9600);
Wire.begin();
radio.init();
radio.debugEnable();
lcd.InitLCD();
lcd.clrScr();
lcd.setFont(SmallFont);
lcd.enableSleep();
power_state = 0;
keypad.addStatedEventListener(keypadEvent);
keypad.setHoldTime(1500);
pinMode(ledPin, OUTPUT);
pinMode(blPin, OUTPUT);
digitalWrite(ledPin, LOW);
digitalWrite(blPin, LOW);
ledPin_state = digitalRead(ledPin);
frequency = mem.readInt(201);
volume = 2;
menu = 1;
if (volume < 0) volume = 0;
if (volume > 15) volume = 15;
if (frequency < 0) frequency = 0;
if (frequency > 210) frequency = 210;
WriteReg(0x02, 0xC00d);
radio.attachReceiveRDS(RDS_process);
rds.attachServicenNameCallback(DisplayServiceName);
rds.attachTextCallback(DisplayText);
}
void loop() {
if (frequency != frequencyOld) {
frequencyOld = frequency;
mem.writeInt(201, frequency);
canal(frequency);
}
if (volume != volumeOld) {
volumeOld = volume;
WriteReg(5, 0x84D0 | volume);
}
char key = keypad.getKey();
radio.checkRDS();
unsigned long timenow = millis();
if ((unsigned long)(timenow - timeprevious) > 600) {
timeprevious = timenow;
samples[temparray] = analogRead(A7);
temparray++;
}
if (temparray == 5) {
float average = 0;
for (int i = 0; i < 5; i++) average += samples[i];
printTemp(average);
temparray = 0;
}
unsigned long dabar = millis();
if (mempress == 1) {
timeprev = dabar;
memdisplay = 1;
mempress = 0;
}
if (memdisplay == 1) {
if ((unsigned long)(dabar - timeprev) < 4000) memdisplay = 1;
else memdisplay = 0;
}
DateTime now = 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(), hours, now.minute(), now.second()));
Serial.println(F("Hours")); Serial.println(hours); break;
}
case 'm': {
unsigned int mins = Serial.parseInt();
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), mins, now.second()));
Serial.println(F("Minutes")); Serial.println(mins); break;
}
case 's': {
unsigned int sec = Serial.parseInt();
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), sec));
Serial.println(F("Seconds")); Serial.println(sec); break;
}
}
}
printSignalStrength();
printLines();
printTime();
printFreq();
printStereo();
printMode();
printMenu();
printDate();
lcd.update();
}
// Funções auxiliares (printSignalStrength, printLines, printTemp, DisplayServiceName,
// DisplayText, printTime, printDate, printMode, printMenu, printFreq, printStereo,
// search, canal, Readstatus, WriteReg, RDS_process, ClearRDS, keypadEvent)
// ... (código completo disponível no projeto original)
Símbolos de Intensidade do Sinal
#if defined(__AVR__)
#include <avr/pgmspace.h>
#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
#endif
imagedatatype signal5[] PROGMEM={ 0xC1, 0xC2, 0xC4, 0xFF, 0xC4, 0xC2, 0xC1, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0xF8, 0xC0, 0xFC, 0xC0, 0xFE };
imagedatatype signal4[] PROGMEM={ 0xC1, 0xC2, 0xC4, 0xFF, 0xC4, 0xC2, 0xC1, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0xF8, 0xC0, 0xFC, 0xC0, 0xC0 };
imagedatatype signal3[] PROGMEM={ 0xC1, 0xC2, 0xC4, 0xFF, 0xC4, 0xC2, 0xC1, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0xF8, 0xC0, 0xC0, 0xC0, 0xC0 };
imagedatatype signal2[] PROGMEM={ 0xC1, 0xC2, 0xC4, 0xFF, 0xC4, 0xC2, 0xC1, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0 };
imagedatatype signal1[] PROGMEM={ 0xC1, 0xC2, 0xC4, 0xFF, 0xC4, 0xC2, 0xC1, 0xC0, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0 };
Esquemáticos
Esquemático do circuito completo disponível na seção de esquemáticos do projeto original.
Processo de manufatura
- A Evolução e Engenharia da Tecnologia de Rádio
- Circuitos Integrados (CIs): Chips Compactos e Poderosos Impulsionando a Eletrônica Moderna
- Gerador de Ondas JX – Oscilador DDS Compatível com Arduino com Display OLED
- MotionSense: Detecção Inteligente de Intrusão com Arduino e ESP8266
- Construa uma Caixa-Puzzle IoT Segura com Arduino MKR Bundle – Guia Passo a Passo
- Regulador de Chuveiro Inteligente - Válvula Solenoide para Controle Preciso de Temperatura
- Scanner IR de Temperatura Sem Fio – Arduino Nano com Bluetooth e MLX90614
- Tanque Autônomo com Walabot, Arduino, Raspberry Pi e Integração Alexa
- Laboratório Avançado de Microcontroladores: ESP32, Arduino, PIC e Módulos de Sensores
- Kit MOSMusic: MOSFET, Arduino e Mais - Iluminação Sincronizada com Música