Выручайте RDA5807M

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем Максим B, 20 июл 2016.

  1. Максим B

    Максим B Гуру

    Код проверим обязательно. Уже заказал еще модулей.
     
  2. Andrey12

    Andrey12 Гик

    Извиняюсь, дела, никак не мог доделать код.
    Задача следующая:
    1. Устанавливаем частоту на которой ЕСТЬ станция у меня это - uint16_t newFrequency = 10490; смотрим что выведет программа в Serial
    2. Устанавливаем частоту на которой НЕТ станции у меня это - uint16_t newFrequency = 10000; смотрим что выведет программа в Serial
    Проверь если не трудно и напиши здесь результат.

    Код (C++):
    #include <Wire.h>

    uint16_t wireRead16()
    {
      uint8_t huint8_t = Wire.read();
      uint8_t luint8_t = Wire.read();
      return (256 * huint8_t + luint8_t);
    }


    void wireWrite16(uint16_t data)
    {
      Wire.write(data >> 8);
      Wire.write(data & 0xFF);
    }

    void regWrite(uint8_t regNum, uint16_t regData)
    {
      Wire.beginTransmission(0x11);
      Wire.write(regNum);
      wireWrite16(regData);
      Wire.endTransmission();
    }

    void setup() {
      Wire.begin();
      Serial.begin(115200);

      // инициализация
      uint8_t initStatus = 0;
      Wire.beginTransmission(0x11);
      initStatus = Wire.endTransmission();
      if (0 == initStatus) {
        uint16_t bufRDA[6] = { 0x03, 0x00, 0xA00, 0x88CF, 0x00, 0x00 };
        Wire.beginTransmission(0x10);
        for (int i = 0; i < 6; i++) {
          wireWrite16(bufRDA[i]);
        }
        Wire.endTransmission();
      }

      delay(1000);
      Serial.print("Init status - ");
      if (0 == initStatus)
      {
        Serial.println("OK");
      }
      else
      {
        Serial.println("ERROR");
      }
      // настройка на станцию
      // установи свою станцию которая у тебя уверенно принимается в формате частота * 100
      // то есть если твоя станция 89.5 то ставить надо 8950
      // у меня лучше всего принимает 104,90 FM
      uint16_t newFrequency = 10490;
      newFrequency = (newFrequency - 8700) / 10;

      uint16_t b2 = 0xC001;
      regWrite(0x02, b2);
      uint16_t b3 = 0;
      b3 = newFrequency << 6;
      b3 = b3 + 16;
      regWrite(0x03, b3);


      // чтение состояния настройки rda5807m
      delay(2000);
      uint16_t bufRDA1[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

      Wire.requestFrom(0x10, 12);
      for (uint16_t i = 0; i < 6; i++) {
        bufRDA1[i] = wireRead16();
      }
      Wire.endTransmission();


      uint16_t state = bufRDA1[1] & 0x180;

      if (0 == state)
      {
        Serial.println("Not ready.");
      }
      else if (128 == state)
      {
        Serial.println("Ready. Station not found.");
      }
      else if (384 == state)
      {
        Serial.println("Ready. Station found.");
      }

    }

    void loop() {

    }
     
  3. Максим B

    Максим B Гуру

    Проверю, отпишусь. Спасибо
     
  4. warman

    warman Гик

    Как говорит мануал на микруху -
    Всего в RDA5807 три интерфейса:
    a) Address 0x60<<1 (TEA5767 compatible mode)
    b) Address 0x10<<1 (sequential access / RDA5800 mode)
    c) Address 0x11<<1 (random access / RDA5807 mode)

    может попробовать по пункту (а) к нему стучатся?
     
  5. Andrey12

    Andrey12 Гик

    А зачем? Кучу плюшек теряем!
    В этом совместимом с TEA5767 режиме нет RDS нет регулировки громкости, нет индикации уровня принимаемого сигнала, да много чего нет....
     
  6. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    здравствуйте всем пытаюсь пределать чужой скетч под ддругой дисплей. и хотел бы сделать идикацию уровня сигнала.
    торетически он находится в этой строке
    Код (C++):
       z=estado[1]>>10; sprintf(buffer,"S-%02d",z); gotoXY(38,0);  LcdString(buffer);
    полный кусок кода визуализации
    Код (C++):
    void Visualizar(void)
    { Serial.println(menuS[menu] );
          //Serial.print("READ_Frecuencia= " );  Serial.println(estado[0] & 0x03ff);
          gotoXY(2,0); LcdStringX("FM");
          sprintf(buffer,"%s",menuS[menu]); gotoXY(2,2);  LcdString(buffer);
           //Detectar se&#241;al stereo
           gotoXY(72,0);
           if((estado[0] & 0x0400)==0)  LcdCharacter(32);   else     LcdCharacter(127);      
           //Se&#241;al
           z=estado[1]>>10; sprintf(buffer,"S-%02d",z); gotoXY(38,0);  LcdString(buffer);  //оригинальная строка z=estado[1]>>10; sprintf(buffer,"S-%02d",z); gotoXY(38,0);  LcdString(buffer);
           sprintf(buffer,"Vol %02d",volumen); gotoXY(38,1);  LcdString(buffer);
           //ver RADIO_TXT
           gotoXY(0,5);
           z1=indexRDS1;
           for (z=0;z<12;z++)
           {        
             LcdCharacter(seg_RDS1[z1]);
             z1++;
             if(z1>35)z1=0;        
           }
           indexRDS1++; if(indexRDS1>35) indexRDS1=0;
         
          frecuencia=estado[0] & 0x03ff;
      }
    весь скетч здесь))) http://full-chip.net/arduino-proekt...7-s-graficheskim-displeem-i-funkciey-rds.html

    пытаюсь получить данные оттуда таким способом
    Код (C++):
     z=estado[1]>>10; disp.display(sprintf("S-%02d",z));
    что то показывает,(наверное погоду на марсе), но в оригинальном коде у него максимальное значение 32 у меня же максимум доходит до 10.

    и еще большой вопрос вызывает строчка включения выключения басов
    Код (C++):
    //включение
    case 5:
               bassbost++;
               if(bassbost++)WriteReg(0x02,0xD00D);
               while(1020>analogRead(entrada))delay(5);
            break;
    //выключение
    case 5:
               bassbost--;
               if(bassbost<0)WriteReg(0x02,0xC00D);
               while(1020>analogRead(entrada))delay(5);
            break;
    в даташите же написано что включить выключить
    reg 02H, bits 12, name BASS, 0 = Disabled; 1 = Bass boost enabled/
    как эту команду правильно написать? если кто в курсе подскажите пожалуйста
     
    Andrey12 нравится это.
  7. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    с басами разобрался. теперь осталось получить данные уровня сигнала. Я пока плотно с I2C не сталкивался поэтому ни бум бум пока в этом вопросе в этом и вся сложность. если кто с этого модуля получал уровень сигнала поделитесь кодом будте добры. лень ковырятся самому)
    в даташите нопесоно;
    REG 0BH
    BITS 15:9
    NAME RSSI[6:0]
    FUNCTION RSSI. 000000 = min 111111 = max RSSI scale is logarithmic/
    буду изучать пока сам эту радость, но все же жду подсказки если кто сталкивался с этим модулем
     
    Последнее редактирование: 18 окт 2017
  8. Andrey12

    Andrey12 Гик

    С уровнем все интересно

    estado[] он заполняет здесь

    Код (C++):
    int ReadEstado()
    {
    Wire.requestFrom(0x10, 12);
    for (int i=0; i<6; i++) { estado[i] = 256*Wire.read ()+Wire.read(); }
    Wire.endTransmission();
    }
     
    если смотрим даташит в регистре по адресу 0BH
    15:9 RSSI[6:0] RSSI. 000000 = min 111111 = max RSSI scale is logarithmic.

    Я так понимаю что всетаки там храниться не 6 а 7 бит с 15 по 9, но еще и шкала логарифмическая. Ну даже если 6 бит то максимальное значение 63 а не 32.
    У себя я заметил что сразу после настройки уровень выдает не очень высокий но в течении очень короткого времени (гдето через 0,01сек после настройки на станцию) происходит расчет уровня и выдаются более высокие показатели.
    То есть если получить флаг настройки на станцию и тут же прочитать уровень он будет низкий но через небольшой промежуток времени чип выдает реальный уровень.
    Хотя судя по коду estado[] обновляется довольно таки часто.

    В принципе правильно
    C00D = 1100000000001101 Выключили бас
    D00D = 1101000000001101 Включили бас

    Но что плохо он не меняет 1 бит а затирает весь регистр.
    при выполнении функции
    Код (C++):
    void busqueda(byte direc)
    {
      byte i;
      if(!direc) WriteReg(0x02,0xC30d); else  WriteReg(0x02,0xC10d);
    Басы сбросятся если они были включены.

    Код читается трудно, надоб экран и работу с радио в отдельные библиотеки вынести.
    В регистры постоянно пишутся значения без учета содержания регистров до этого.

    Посмотрел видео, там тоже видно что при настройке уровень увеличивается через некоторое время после окончания настройки. Почему максимум 32 это интересно, у меня при 32 RDS не стабильно очень читается.
     
    CYITEP_BAC9I нравится это.
  9. Andrey12

    Andrey12 Гик

    О ты и сам уже влез в даташит
    Ну смотри в регистре 16 бит с 15 по 9 хранится уровень сигнала
    УУУУУУУХХХХХХХХХ
    то есть Y это уровень сигнала а X это остальные данные в регистре, они нам не нужны, происходит сдвиг на 10
    z=estado[1]>>10; у нас остается в z только 6 битов, надо оставить 7 так как в даташите сказано что с 15 по 9
    попробуй исправить на
    z=estado[1]>>9; посмотри что получится. Под рукой нет платы не на чем проверить самому. Опять же загадочные слова что шкала не линейная а scale is logarithmic
    Если найдешь как ее переводить в линейную отпишись, тоже интересно.
     
    CYITEP_BAC9I нравится это.
  10. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    спасибо большое. благодаря вашему объяснению понял как читаются биты с регистров. чего не смог сделать читая книжки. (это самое ценное[​IMG])

    перерыл весь Гугл но про эту шкалу логарифмическую так и не нашел ничего. единственно в каком то забугорном скетче наткнулся на какого то романтика который тоже пытался его разгадать. по памяти там к результату считывания добавлялась 4 зачем то, затем результат масштабировался map между 16 и 32, зачем не знаю. по закону подлости именно в этот момент появилось начальство и пришлось резко все закрыть, сохранить не успел. но постараюсь найти. Хотя по моему пользы мало будет. но поищу.
    Согласен стиль написания скетча очень тяжелый, чуть мозги не свихнул пока понял что к чему.
    я это скетч адаптировал под индикатор TM1637) без текста прочих плюшек, но получилось неплохо. вот и хотел что бы меню инфо не пропадало впихнуть туда данные о силе сигнала.
    как отлажу выложу скетч сюда. на макетке уже все работает осталось силу сигнала допилить.
    z=estado[1]>>9; как все уснут чтоб не мешали ночью как Ленин сяду работать), завтра утром о результатах напишу.
     
  11. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    получилось даже раньше)) вставил z=estado[1]>>9; цифры стали что показывать максимум до 21. причем показания стали наоборот) при 0 - 3, отличный стереоприем. при 7-10 прием становился явно моно но все еще хорошого качества при 21 вообще пропадал прием одно шипение. ради интереса попробую все та получить "истинные" данные. а пока сделаю так 32 минус полученные даные. Вот и получится хоть фигня но фигня приближенная к правде). при 32 будет отличный сигнал, при 9 сигнала нет. очень даже похоже на правду.
    попробую поковырять еще
     
    Andrey12 нравится это.
  12. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    есть некоторое предположение, что решил вопрос. в извращенной форме надругавшись над скетчем и над переменной.
    Код (C++):
    int  z=estado[1]>>9;    disp.display(z);  
    обьявил int z (не думал, что этот фикус прокатит)
    но теперь максимум показал 64 ( у меня вышка из окна видна) и если за компьютер заходишь прием становиться хуже и цифры намного меньше. вот думаю сделать map до 32, как в оригинальном скетче или оставить так? типо это фича моего скетча.
    спасибо вам большое, что натолкнули на правильный путь!!!
    допилю скетчь и выложу (если комуто интересно будет) он прекрасно адаптирует TM1637 к этому модулю.
    может еще на TM1637 rds сделать)))
     
    Последнее редактирование: 18 окт 2017
    Andrey12 нравится это.
  13. Andrey12

    Andrey12 Гик

    Только сейчас разглядел.
    disp.display(sprintf("S-%02d",z));
    Вот описание sprintf - http://www.cplusplus.com/reference/cstdio/sprintf/
    Получается что вы выводите количество символов а не сами символы, sprintf не возвращает результат а помещает его в буфер. то есть так:
    количество символов = sprintf(куда, формат, что)
    А у вас просто выводится размер содержания переменной buffer.

    Код (C++):
     
    char buffer[30];
    z=estado[1]>>9;
    sprintf(buffer,"S-%02d",z);
    disp.display(buffer);
     
    Автор просто окультуривал результат чтобы выводился лидирующий 0 если число меньше 10.
    А с уровнем сигнала вам везет у меня не более 45-50 ну насколько я помню.

    Лучше мапить 64 до 100 то есть 0-0 64-100, получится вполне понятно в процентах.
     
    CYITEP_BAC9I нравится это.
  14. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    здравствуйте . Еще раз спасибо за разъяснения!!!
    Код (C++):

    char buffer[30];
    z=estado[1]>>9;
    sprintf(buffer,"S-%02d",z);
    disp.display(buffer);
     
    не прошло(( компилятор ругается матом. оставил все как есть.
    ниже сылки на скетч и библиотеку к дисплею . я туда добавил символы для отоборажения названий меню. скетч рабочий. единственно иногда при быстром нажатии на кнопу "меню" "пролетают" заголовки меню. в чем цимес не понял, может обработка антидребезга не идеальна. постораюсь нарисовать схему подключения к услителю. как только время появится.
    (если есть ошибки то это не от неграмотности, а побочный эффект скоростного набора))
    https://drive.google.com/file/d/0B2kaRZ6OgtCPOVBtZ3A3eXJQUWM/view?usp=sharing модернизированная библиотека TM1637
    https://drive.google.com/file/d/0B2kaRZ6OgtCPd1M2WXBQZ3o1djg/view?usp=sharing скетч
     
  15. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    чтоб не задерживать нарисовал от руки схему подключения к усилителю.
    [​IMG]
    это единственная схема при которой получилось подключиться к усилителю не спалив модуль. единственно я не согласен с резисторами по 33 ома (сильно маленькое сопротивление по моему) но все работает.
    сейчас думаю как избежать щелчка при включении. усилок тоже самодельный 10 вт и при включении очень неприятный щелчек. думаю над 2 вариантами или через IRF630 или что то подобное включать - через ногу ардуины спустя 2-3 секунды после включения. или поставить реле которое бы подключало услитель так же с задержкой. С уважением
     
    Andrey12 нравится это.
  16. IvanUA

    IvanUA Гуру

    А если при включении сразу делать MUTE, а потом подымать громкость, то тоже клацает?
     
    Andrey12 нравится это.
  17. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    бесполезно. все перепробовал. это не шелчек в полном понимании а какоето короткое время шпарит на полную громкость частота которая установлена по умолчанию. надо попробовать найти частоту на которой нет станций. может это сработает. а пока решил включать отключать +(плюс) питания усилителя через реле спустя 3 секунды после включения. кстати сечас мой модуль если подключить без ардуины проигрывает ту самую станцию которая забита в скетче))) на максимальной громкости. почему так не пойму. по моему еепрома в модуле нет или плохо даташит читал.
     
    Andrey12 нравится это.
  18. Andrey12

    Andrey12 Гик

    Я подключал как усилитель PAM8403. При включении щелчков нет.
    Но у меня колонки старенькие к компу подключены, даже когда они не подключены к компу и громкость выкручена в ноль, при подаче питания всегда громкий такой щелчок!

    В вашем случае 33 ома это какаято жесть! Делитель поставьте если очень чувствительный усилок. Типа так как нибудь.
    234Снимок.JPG

    Станцию сохраняет это точно, на громкость внимания не обращал. В принципе можно попробовать в самом начале Setup() поставить чтобы громкость была минимальная. Но мне всетаки кажется настройки должны сохраняться.
     
    CYITEP_BAC9I нравится это.
  19. IvanUA

    IvanUA Гуру

    На сколько помню, радио всегда стартовало с нормальной громкостью (заданной в сетапе).
    Код (C++):
    void setup() {
    //delay(300);                               // Пауза 0,3 сек
      Serial.begin(9600);                       // Скорость серийного порта
      time.begin();                             // Инициализация часового модуля
      //time.settime(30,37,12,19,02,17,7);      // Установка времени сек,мин,час,день,месяц,год,день недели
      lcd.begin();                              // Инициализация lcd
      lcd.backlight();                          // Инициализация подсветки ???
      dht.begin();                              // Инициализация DHT датчика
      setupLcd();
      pinMode (SVET, OUTPUT);                   // пин резулировки яркости работает как выход
      analogWrite(SVET, 25);                    // Максимальный уровень на выходе 5V = 255единиц
      pinMode(pinklav, INPUT);

      radio.init();                                      // инициализируем радио
      radio.debugEnable();                               // Включение информации к последовательному порту
      radio.setBandFrequency(RADIO_BAND_FM, preset[i_sidx]); // Установка канала preset

      radio.setMono(false);                              // -_saveRegister(0x2, 0xC009)
      radio.setMute(false);                              // -_saveRegister(0x2, 0xC009)
      //radio.debugRegisters();
      radio.setVolume(2);                                // -_saveRegister(0x5, 0x9088)

      state = STATE_PARSECOMMAND;

      radio.attachReceiveRDS(RDS_process);                 // Настройка информационной цепочки для данных RDS.
      rds.attachServicenNameCallback(DisplayServiceName);
      rds.attachTimeCallback(DisplayTime);
    }
     
    CYITEP_BAC9I и Andrey12 нравится это.
  20. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    Вечер добрый. продолжим художественные изыски). если на то пошло то можно и потенциометр пристроить. Для PAM8403 это тоже актуально, у вроде нет регулировки громкости.
    [​IMG]
    правда выбор сдвоенных потенциометров небольшо или 680 ом или 10Ком. наверное первый поставлю, так как 10Ком перебор.
    IvanUA, спасибо за скетч, сегодня вечером постараюсь загнать его в Дуню. Тоже думаю что, дело что то в коде который я за основу взял(блин плохая привычка тянуть что первое попадется под руку). сейчас подумал, что с 0 написать было бы проще и быстрей. но сейчас уже лень) и так работает.
    если дело в коде то есть некоторые предположение , что в ФМ модуле все же есть какаято запоминалка)
     
    Andrey12 нравится это.