Приемник в спящем режиме 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 ответ
Лучший ответ:
Выключите:
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);
}
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- Как перевести ATtiny/ATmega в режим глубокого сна (чтобы годами работать от батарей), но при этом обнаруживать нажатие кнопки?
- Невозможно преобразовать 'int (*)[size]' в 'int**': Cannot convert 'int (*)[size]' to 'int**'
- Как удалить элемент из массива arduino?
- Как передать несколько переменных в функцию?
- ESP8266 глубокий сон и MQTT
- ESP.deepSleep() — снова и снова?
- Есть ли функция Adafruit для инвертирования цветов моего экрана для языка Arduino?
Спасибо, я исправил код в соответствии с вашим предложением. Если вы поможете мне избавиться от двух ненужных аргументов, я буду вам еще более благодарен, @Антон
Спасибо, я все сделал, как ты сказал, все работает, я счастлив. Мы также исправили некоторые ошибки, спасибо!, @Антон