Приемник в спящем режиме RDA5807M

Добрый день, ребята! У меня есть радиоприемник, подключенный к arduino, и я хочу, чтобы он работал не все время, а включался по таймеру arduino в течение определенного времени, а в остальное время приемник должен быть выключен программным обеспечением. У меня есть рабочий скетч, который позволяет настроить этот приемник, а также позволяет повторно настроить приемник (установить громкость и частоту), вызвав функцию.

#include <Wire.h>

#define RDA5807M_RANDOM_ACCESS_ADDRESS 0x11
// регистры
#define RDA5807M_REG_CONFIG 0x02
#define RDA5807M_REG_TUNING 0x03
#define RDA5807M_REG_VOLUME 0x05
// флаги
#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)
//маски
#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); // Настройка приемника: вкл. или выключено (включено, выключено), громкость (0 ... 15), частота МГц * 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
  // После сброса в регистре 03 часа значение по умолчанию равно 0
  // Таким образом, ПОЛОСА = 00 (87..108 МГц), ШАГ = 00 (100 кГц). Давайте оставим их такими, какие они есть
  reg03h = (freq - 870) << RDA5807M_CHAN_SHIFT; // chan = (freq - band) / space
  setRegister(RDA5807M_REG_TUNING, reg03h | RDA5807M_FLG_TUNE);

  //Регистр 05h. Установите громкость, не меняйте остальные удары
  reg05h = getRegister(RDA5807M_REG_VOLUME); // Чтение текущего значения
  reg05h &= ~RDA5807M_VOLUME_MASK; // Сброс громкости
  reg05h |= volume << RDA5807M_VOLUME_SHIFT; // Установка нового значения
  setRegister(RDA5807M_REG_VOLUME, reg05h);
}

Мне нужно изменить этот скетч и добавить возможность разбудить приемник и перевести его в спящий режим. Здесь есть "RDA5807M_FLG_ENABLE". Как я понимаю, вам нужно его изменить?

Добавлено позже:

Метод отключения приемника на некоторое время, предложенный в комментариях, работает. Однако, чтобы все было правильно, при вызове функции при отключении приемника мы отправим настройку(0, 4, 1077); то есть при выключении мы все равно указываем громкость и частоту, хотя эти параметры здесь излишни. Правильно было бы написать просто Nastroika(0); , Но это нельзя сделать просто так, потому что у функции должно быть ровно три входных аргумента, а не один.

, 👍1


1 ответ


Лучший ответ:

2

Выключите:

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

Включите:

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

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

Nastroika (настройка) means "tuning". Это правда? Тогда я бы использовал этот метод только для настройки. Создайте два метода, один для выключения, а другой для включения.

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

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

В методе Nastroika вы должны только выполнить настройку и позволить модулю. Если вы настаиваете на одновременном включении, вы можете использовать свою старую версию.

Пример:

void Nastroika(uint8_t volume, uint16_t freq) 
{
   // !!!!! Это неподходящее место для начала провода
   // переместите его в метод настройки.
   // Wire.begin();
   reg02h = reg02h | RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE;
   // или если вы настаиваете / вы хотите, чтобы модуль был запущен здесь
   // 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);
}

Использование:

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

void loop() 
{
  switchOff();
  delay(5000);
  switchOn();
  delay(5000);
}
,

Спасибо, я исправил код в соответствии с вашим предложением. Если вы поможете мне избавиться от двух ненужных аргументов, я буду вам еще более благодарен, @Антон

Спасибо, я все сделал, как ты сказал, все работает, я счастлив. Мы также исправили некоторые ошибки, спасибо!, @Антон