Grove - I2C FM Receiver v1.1

Från Karlskrona Makerspace Wiki
Version från den 3 februari 2021 kl. 15.17 av Christian (diskussion | bidrag)
Hoppa till: navigering, sök
Grove - I2C FM Receiver v1.1

Kompatibilitet

  • Arduino

Port

  • I2C

Bibliotek

https://github.com/mathertel/Radio/

Exempelkod

Arduino

#include <Wire.h>

#include <radio.h>
#include <RDA5807M.h>
#include <SI4703.h>
#include <SI4705.h>
#include <TEA5767.h>

#include <RDSParser.h>

/// The radio object has to be defined by using the class corresponding to the used chip.
/// by uncommenting the right radio object definition.

// RADIO radio;       ///< Create an instance of a non functional radio.
// RDA5807M radio;    ///< Create an instance of a RDA5807 chip radio
// SI4703   radio;    ///< Create an instance of a SI4703 chip radio.
SI4705   radio;    ///< Create an instance of a SI4705 chip radio.
// TEA5767  radio;    ///< Create an instance of a TEA5767 chip radio.

/// get a RDS parser
RDSParser rds;

/// State definition for this radio implementation.
enum SCAN_STATE {
  STATE_START,      ///< waiting for a new command character.
  STATE_NEWFREQ,
  STATE_WAITFIXED,
  STATE_WAITRDS,
  STATE_PRINT,
  STATE_END          ///< executing the command.
};

SCAN_STATE state; ///< The state variable is used for parsing input characters.

uint16_t g_block1;

// - - - - - - - - - - - - - - - - - - - - - - - - - -


// use a function inbetween the radio chip and the RDS parser
// to catch the block1 value (used for sender identification)
void RDS_process(uint16_t block1, uint16_t block2, uint16_t block3, uint16_t block4) {
  g_block1 = block1;
  rds.processData(block1, block2, block3, block4);
}

/// Update the ServiceName text on the LCD display.
void DisplayServiceName(char *name)
{
  bool found = false;

  for (uint8_t n = 0; n < 8; n++)
    if (name[n] != ' ') found = true;

  if (found) {
    Serial.print("RDS:");
    Serial.print(name);
    Serial.println('.');
  }
} // DisplayServiceName()


/// Execute a command identified by a character and an optional number.
/// See the "?" command for available commands.
/// \param cmd The command character.
/// \param value An optional parameter for the command.
void runSerialCommand(char cmd, int16_t value)
{
  unsigned long startSeek; // after 300 msec must be tuned. after 500 msec must have RDS.
  RADIO_FREQ fSave, fLast;
  RADIO_FREQ f = radio.getMinFrequency();
  RADIO_FREQ fMax = radio.getMaxFrequency();
  char sFreq[12];
  RADIO_INFO ri;

  if (cmd == '?') {
    Serial.println();
    Serial.println("? Help");
    Serial.println("+ increase volume");
    Serial.println("- decrease volume");
    Serial.println("1 start scan version 1");
    Serial.println("2 start scan version 2");
    Serial.println(". scan up   : scan up to next sender");
    Serial.println(", scan down ; scan down to next sender");
    Serial.println("i station status");
    Serial.println("s mono/stereo mode");
    Serial.println("b bass boost");
    Serial.println("u mute/unmute");
  }

  // ----- control the volume and audio output -----

  else if (cmd == '+') {
    // increase volume
    int v = radio.getVolume();
    if (v < 15) radio.setVolume(++v);
  } else if (cmd == '-') {
    // decrease volume
    int v = radio.getVolume();
    if (v > 0) radio.setVolume(--v);
  }

  else if (cmd == 'u') {
    // toggle mute mode
    radio.setMute(!radio.getMute());
  }

  // toggle stereo mode
  else if (cmd == 's') { radio.setMono(!radio.getMono()); }

  // toggle bass boost
  else if (cmd == 'b') { radio.setBassBoost(!radio.getBassBoost()); }

  // ----- control the frequency -----

  else if (cmd == '1') {
    Serial.println("Scanning all available frequencies... (1)");
    fSave = radio.getFrequency();

    // start Simple Scan: all channels
    while (f <= fMax) {
      radio.setFrequency(f);
      delay(50);

      radio.getRadioInfo(&ri);
      if (ri.tuned) {
        radio.formatFrequency(sFreq, sizeof(sFreq));
        Serial.print(sFreq);
        Serial.print(' ');

        Serial.print(ri.rssi); Serial.print(' ');
        Serial.print(ri.snr); Serial.print(' ');
        Serial.print(ri.stereo ? 'S' : '-');
        Serial.print(ri.rds ? 'R' : '-');
        Serial.println();
      } // if

      // tune up by 1 step
      f += radio.getFrequencyStep();
    } // while
    radio.setFrequency(fSave);
    Serial.println();

  } else if (cmd == '2') {
    Serial.println("Seeking all frequencies... (2)");
    fSave = radio.getFrequency();

    // start Scan
    radio.setFrequency(f);

    while (f <= fMax) {
      radio.seekUp(true);
      delay(100); // 
      startSeek = millis();

      // wait for seek complete
      do {
        radio.getRadioInfo(&ri);
      } while ((!ri.tuned) && (startSeek + 300 > millis()));

      // check frequency
      f = radio.getFrequency();
      if (f < fLast) {
        break;
      }
      fLast = f;

      if ((ri.tuned) && (ri.rssi > 42) && (ri.snr > 12)) {
        radio.checkRDS();

        // print frequency.
        radio.formatFrequency(sFreq, sizeof(sFreq));
        Serial.print(sFreq);
        Serial.print(' ');

        do {
          radio.checkRDS();
          // Serial.print(g_block1); Serial.print(' ');
        } while ((!g_block1) && (startSeek + 600 > millis()));

        // fetch final status for printing
        radio.getRadioInfo(&ri);
        Serial.print(ri.rssi); Serial.print(' ');
        Serial.print(ri.snr); Serial.print(' ');
        Serial.print(ri.stereo ? 'S' : '-');
        Serial.print(ri.rds ? 'R' : '-');

        if (g_block1) {
          Serial.print(' ');
          Serial.print('[');  Serial.print(g_block1, HEX); Serial.print(']');
        } // if
        Serial.println();
      } // if
    } // while
    radio.setFrequency(fSave);
    Serial.println();


  } else if (cmd == 'f') { radio.setFrequency(value); }

  else if (cmd == '.') { radio.seekUp(false); } else if (cmd == ':') { radio.seekUp(true); } else if (cmd == ',') { radio.seekDown(false); } else if (cmd == ';') { radio.seekDown(true); }


  // not in help:
  else if (cmd == '!') {
    if (value == 0) radio.term();
    if (value == 1) radio.init();

  } else if (cmd == 'i') {
    char s[12];
    radio.formatFrequency(s, sizeof(s));
    Serial.print("Station:"); Serial.println(s);
    Serial.print("Radio:"); radio.debugRadioInfo();
    Serial.print("Audio:"); radio.debugAudioInfo();

  } // info

  else if (cmd == 'x') {
    radio.debugStatus(); // print chip specific data.
  }
} // runSerialCommand()


/// Setup a FM only radio configuration with I/O for commands and debugging on the Serial port.
void setup() {
  // open the Serial port
  Serial.begin(57600);
  Serial.print("Radio...");
  delay(500);

  // Initialize the Radio 
  radio.init();

  // Enable information to the Serial port
  radio.debugEnable();

  radio.setBandFrequency(RADIO_BAND_FM, 8930);

  // delay(100);

  radio.setMono(false);
  radio.setMute(false);
  // radio.debugRegisters();
  radio.setVolume(5);

  Serial.write('>');

  // setup the information chain for RDS data.
  radio.attachReceiveRDS(RDS_process);
  rds.attachServicenNameCallback(DisplayServiceName);

  runSerialCommand('?', 0);
} // Setup


/// Constantly check for serial input commands and trigger command execution.
void loop() {
  char c;
  if (Serial.available() > 0) {
    // read the next char from input.
    c = Serial.read();
    runSerialCommand(c, 8930);
  } // if

  // check for RDS data
  radio.checkRDS();


} // loop


Mer information

http://wiki.seeedstudio.com/Grove-I2C_FM_Receiver_v1.1/