Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Waterdichte FM-radio voor de douche bouwen met Arduino Nano, RDA5807, Nokia LCD & PAM8403

Onderdelen en benodigdheden

  • Arduino Nano R3 (1×)
  • RDA5807 FM-radio module (1×)
  • Nokia 5110 LCD 3,3–5 V versie (1×)
  • Tiny RTC module (DS1307 + 24C32 EEPROM) (1×)
  • PAM8403 2×3 W klasse-D versterker (1×)
  • LM2596 DC-DC step-down converter (1×)
  • LIR2032 3,6 V oplaadbare knoopcel (1×)
  • Weerstanden: 100 Ω (1), 1 kΩ (1), 10 kΩ (6), 100 kΩ (1)
  • IRLZ44 power MOSFET (1×)
  • PEIYING PY1010C 60 W 4 Ω luidsprekers (1 paar)
  • 12 V 3 A voeding (uit slop) (1×)
  • 2200 µF 25 V condensators (2×)
  • 100 µF condensator (1×)
  • 3 W LED-lampen (voor G4 halogeenvervanging) (1×)

Over dit project

Een paar jaar geleden kocht ik een Chinese douchecabine met ingebouwde TR028-besturing en radio. Die viel na een tijd uit elkaar en kon niet gerepareerd worden. Een goedkopere doucheradio hield ook maar een jaar. Omdat mijn gezin gewend was aan radio in de douche, besloot ik er zelf een te bouwen.

In de TR028 zat een TEA5767-module. Onderzoek leverde de RDA5807 op: vergelijkbaar, maar met RDS, volumeregeling en bass boost. Ik bestelde de benodigde modules (RDA5807, Tiny RTC, PAM8403, Nokia 5110 LCD, LM2596) voor minder dan 10 € en ging experimenteren.

Mijn visie

  • Apparaat met touchscreen voor waterdichte constructie (behuizing van defecte TR028 hergebruikt).
  • FM-radio met RDS (2 regels).
  • 6 favoriete zenders als presets.
  • Automatische en handmatige zoekfunctie.
  • Gevonden zender opslaan in een preset.
  • Volume- en bass-regeling.
  • Douchecabine-verlichting besturen.
  • Klok en kalender.
  • RSSI (signaalsterkte-indicator) en stereo-indicator.
  • Aan/uit-functie.

Wat er uiteindelijk uitkwam

  • FM-radio met 2-regels RDS.
  • 6 presets.
  • Auto/handmatig afstemmen.
  • Opslaan in preset (4 seconden na Mem-toets).
  • Volume en bass boost.
  • Verlichtingsbesturing.
  • Klok en kalender.
  • RSSI en stereo-indicator.
  • Aan/uit.

Foto’s van het project

Waterdichte FM-radio voor de douche bouwen met Arduino Nano, RDA5807, Nokia LCD & PAM8403
Waterdichte FM-radio voor de douche bouwen met Arduino Nano, RDA5807, Nokia LCD & PAM8403
Waterdichte FM-radio voor de douche bouwen met Arduino Nano, RDA5807, Nokia LCD & PAM8403
Waterdichte FM-radio voor de douche bouwen met Arduino Nano, RDA5807, Nokia LCD & PAM8403

Hoe het werkt

  • Aan/uit: Na aansluiten voeding speelt radio niet direct. Druk op Power-toets → radio start met laatste zender, volume 03, mode VOLUME. Nogmaals Power → uit (LCD, backlight, versterker, lamp uit).
  • Zoeken: Mod-toets wisselt tussen Auto en Manual. < / > zoeken naar beneden/boven. Mem-toets → 4 sec om preset 1–6 te kiezen.
  • Datum tonen: I-toets → datum 4 sec (gebruikt delay, kan geoptimaliseerd).
  • Klok instellen: Houd D-toets ≥ 2 sec in bij uurslag (tijdsein of nauwkeurige klok). Loslaten stelt minuten/seconden op 00; als klok 1–15 min achterloopt gaat uur omhoog, bij 15–59 min blijft uur gelijk.

Wat ik zou verbeteren

  • Resonator op RTC voor betere nauwkeurig (instelfunctie lost deels op).
  • Groter, helderder display (bijv. 1,8″ of 2,0″ kleur TFT) – Nokia 5110 is soms slecht leesbaar.
  • Stärkere versterker: PAM8610 (2×15 W) of TDA7297.

Conclusie

Ik ben tevreden over het resultaat; na een maand werken geen problemen behalve kloknauwkeurigheid. De code kan nog geoptimaliseerd worden (mijn eerste nuttige Arduino-project). Vragen? Stel ze in de reacties.

Update 1: 2 A zekering op 12 V lijn voor veiligheid; software: regel 586 menu = 1; herstelt VOLUME-mode na Power-toets.

Update 2: LCD begint te sterven; zoek goedkope vervanger (1,8″ TFT?), advies welkom.

Code

Project sketch (Arduino)

/////////////////////////////////////////////////////////////////
// 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 1-2
  {'3','4'}, // presets 3-4
  {'5','6'}, // presets 5-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, 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();

  // Temperatuurmeting elke 0,6 s, gemiddelde over 5 samples
  float average;
  unsigned long timenow = millis();
  if ((timenow - timeprevious) > 600) {
    timeprevious = timenow;
    samples[temparray] = analogRead(A7);
    temparray++;
  }
  if (temparray == 5) {
    average = 0;
    for (int i = 0; i < 5; i++) average += samples[i];
    printTemp(average);
    temparray = 0;
  }

  // 4-sec timeout voor MEM display
  unsigned long dabar = millis();
  if (mempress == 1) { timeprev = dabar; memdisplay = 1; mempress = 0; }
  if (memdisplay == 1) {
    if ((dabar - timeprev) < 4000) memdisplay = 1; else memdisplay = 0;
  }

  // Seriële klokinstelling (hXX, mXX, sXX)
  if (Serial.available() > 0) {
    char t = Serial.read();
    DateTime now = rtc.now();
    switch (t) {
      case 'h': { unsigned int h = Serial.parseInt(); rtc.adjust(DateTime(now.year(), now.month(), now.day(), h, now.minute(), now.second())); Serial.println(F("Hours")); Serial.println(h); break; }
      case 'm': { unsigned int m = Serial.parseInt(); rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), m, now.second())); Serial.println(F("Minutes")); Serial.println(m); break; }
      case 's': { unsigned int s = Serial.parseInt(); rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), s)); Serial.println(F("Seconds")); Serial.println(s); break; }
    }
  }

  printSignalStrength();
  printLines();
  printTime();
  printFreq();
  printStereo();
  printMode();
  printMenu();
  printDate();
  lcd.update();
}

// ... (hulp-functies: printSignalStrength, printLines, printTemp, DisplayServiceName, DisplayText, printTime, printDate, printMode, printMenu, printFreq, printStereo, search, canal, Readstatus, WriteReg, RDS_process, ClearRDS, keypadEvent) ...

Signaalsterkte-symbolen (C/C++)

#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 };

Schema's

Waterdichte FM-radio voor de douche bouwen met Arduino Nano, RDA5807, Nokia LCD & PAM8403

Productieproces

  1. De Evolutie en Engineering van Radiotechnologie
  2. Geïntegreerde Schakelingen (IC's): Compacte, Krachtige Chips die Moderne Elektronica Aandrijven
  3. JX Wave Generator – Arduino-compatibele DDS-oscillator met OLED-display
  4. MotionSense: Slimme inbraakdetectie met Arduino en ESP8266
  5. Bouw een Veilige IoT Puzzeldoos met Arduino MKR Bundle – Stap-voor-Stap Handleiding
  6. Slimme doucheregulator – Betrouwbare magnetklep voor nauwkeurige temperatuurcontrole
  7. Draadloze IR-temperatuurscanner – Arduino Nano met Bluetooth & MLX90614
  8. Zelf een autonomere tank bouwen: Walabot, Arduino, Raspberry Pi & Alexa-integratie
  9. Geavanceerde Microcontroller Lab: ESP32, Arduino, PIC en Sensormodules
  10. MOSMusic Project Kit: MOSFET, Arduino en meer
  11. Slimme polsband bouwen met Arduino MKR GSM 1400 en Hologram IoT