1

Good afternoon guys! I have a radio receiver connected to an arduino and I want it not to work all the time, but to turn on by the arduino timer for a certain time, and the rest of the time the receiver must be turned off by software. I have a working sketch that allows you to tune this receiver, and it also allows you to re-tune the receiver (set the volume and frequency) by calling a function.

#include <Wire.h>

#define RDA5807M_RANDOM_ACCESS_ADDRESS 0x11
// registers
#define RDA5807M_REG_CONFIG 0x02
#define RDA5807M_REG_TUNING 0x03
#define RDA5807M_REG_VOLUME 0x05
// flags
#define RDA5807M_FLG_DHIZ 0x8000
#define RDA5807M_FLG_DMUTE 0x4000
#define RDA5807M_FLG_BASS 0x1000
#define RDA5807M_FLG_ENABLE word(0x0001)
#define RDA5807M_FLG_TUNE word(0x0010)
//masks
#define RDA5807M_CHAN_MASK 0xFFC0
#define RDA5807M_CHAN_SHIFT 6
#define RDA5807M_VOLUME_MASK word(0x000F)
#define RDA5807M_VOLUME_SHIFT 0
#define RDA5807M_RSSI_MASK 0xFE00
#define RDA5807M_RSSI_SHIFT 9

//uint8_t volume; // 0..15
//uint16_t freq = 1077; // 107.3FM
uint16_t reg02h, reg03h, reg05h, reg0Bh;


void setup() {
  Serial.begin(9600);
  Nastroika(1, 4, 1077); // Receiver setting: incl. or off (on, off), volume (0 ... 15), frequency MHz * 10 (107.7 = 1077)
}

void loop() {
  Nastroika(1, 4, 1077);
  delay(5000);
  Nastroika(0, 4, 1077); // Nastroika(0)
  delay(5000);
}

void setRegister(uint8_t reg, const uint16_t value) {
  Wire.beginTransmission(0x11);
  Wire.write(reg);
  Wire.write(highByte(value));
  Wire.write(lowByte(value));
  Wire.endTransmission(true);
}

uint16_t getRegister(uint8_t reg) {
  uint16_t result;
  Wire.beginTransmission(RDA5807M_RANDOM_ACCESS_ADDRESS);
  Wire.write(reg);
  Wire.endTransmission(false);
  Wire.requestFrom(0x11, 2, true);
  result = (uint16_t)Wire.read() << 8;
  result |= Wire.read();
  return result;
}


void Nastroika(byte Key, uint8_t volume, uint16_t freq) // Receiver configuration after power failure
{
  Wire.begin();
  // Регистр 02h - inclusion, settings
  if (Key == 1)
  {
    reg02h = reg02h | RDA5807M_FLG_ENABLE | RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE;
  }
  else if (Key == 0)
  {
    reg02h = reg02h & ~RDA5807M_FLG_ENABLE | RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE;

  }
  setRegister(RDA5807M_REG_CONFIG, reg02h);
  // Регистр 03h - radio station selection
  // After reset in register 03h, the default value is 0
  // Thus BAND = 00 (87..108MHz), STEP = 00 (100kHz). Let's leave them as they are
  reg03h = (freq - 870) << RDA5807M_CHAN_SHIFT; // chan = (freq - band) / space
  setRegister(RDA5807M_REG_TUNING, reg03h | RDA5807M_FLG_TUNE);

  //Register 05h. Set the volume, do not change the rest of the beats
  reg05h = getRegister(RDA5807M_REG_VOLUME); // Reading the current value
  reg05h &= ~RDA5807M_VOLUME_MASK; // Resetting the bits VOLUME
  reg05h |= volume << RDA5807M_VOLUME_SHIFT; // Setting a new volume
  setRegister(RDA5807M_REG_VOLUME, reg05h);
}

I need to modify this sketch and add the ability to wake up the receiver and put it into sleep mode. There is "RDA5807M_FLG_ENABLE" here. As I understand it, you need to change it?

Added later:

The method of turning off the receiver for a while, suggested in the comments, works. However, for everything to be correct, when calling the function when the receiver is disconnected, we will send Nastroika(0, 4, 1077); that is, when turning off, we still specify the volume and frequency, although these parameters are superfluous here. It would be correct to write simply Nastroika(0); , But this cannot be done just like that, because there should be exactly three input arguments for the function, and not one.

2

Switch off:

reg02h = reg02h & ~RDA5807M_FLG_ENABLE;
setRegister(RDA5807M_REG_CONFIG, reg02h);

Switch on:

reg02h = reg02h | RDA5807M_FLG_ENABLE;
setRegister(RDA5807M_REG_CONFIG, reg02h);

EDIT: (to answer a comment of Антон)

Nastroika (настройка) means "tuning". Is that right? Then I would use this method only for tuning. Create two methods one for switching off and one for switching on.

void switchOff()
{
   reg02h = reg02h & ~RDA5807M_FLG_ENABLE;
   setRegister(RDA5807M_REG_CONFIG, reg02h);
}

void switchOn()
{
   reg02h = reg02h | RDA5807M_FLG_ENABLE;
   setRegister(RDA5807M_REG_CONFIG, reg02h);
}

In the Nastroika Method you should only perform the tuning and let the module of. If you insist to switch on at the same time you could use your old version.

Example:

void Nastroika(uint8_t volume, uint16_t freq) 
{
   // !!!!! This is the wrong place for Wire begin
   // move it to the setup method.
   // Wire.begin();
   reg02h = reg02h | RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE;
   // or if you insist / you want to keep the module be started here
   // reg02h = reg02h | RDA5807M_FLG_ENABLE | RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE;
   setRegister(RDA5807M_REG_CONFIG, reg02h);
   reg03h = (freq - 870) << RDA5807M_CHAN_SHIFT; 
   setRegister(RDA5807M_REG_TUNING, reg03h | RDA5807M_FLG_TUNE);

   reg05h = getRegister(RDA5807M_REG_VOLUME); 
   reg05h &= ~RDA5807M_VOLUME_MASK;
   reg05h |= volume << RDA5807M_VOLUME_SHIFT;
   setRegister(RDA5807M_REG_VOLUME, reg05h);
}

Usage:

void setup() 
{
   Serial.begin(9600);
   Wire.begin();
   Nastroika(4, 1077); 
}

void loop() 
{
  switchOff();
  delay(5000);
  switchOn();
  delay(5000);
}
2
  • Thanks, I corrected the code according to your suggestion. If you can help me get rid of two unnecessary arguments, I will be even more grateful to you – Антон Feb 13 at 11:55
  • Thank you, I did everything as you said, everything works, I'm happy. We've also fixed some bugs, thank you! – Антон Feb 14 at 11:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.