Wednesday, December 31, 2014

FM radio receiver for your Arduino (TEA5767/TEA5768/TEA5757)
(Part 2/4)





Abstract

In this second part we provide C++ classes to deal with TEA576X family of chips. We also provide a basic sketch for using the TEA5767HN module that one may buy for few bucks. The next post will be concerned with the FM module and the last one will provide an example of (basic) FM Radio as an application of the FM module.


Updated

After further tests some bugs were found. Here is the list:
  • Read procedures in TEA5767HN.cpp and TEA5768HL.cpp
  • #define constants in TEA576X.h
  • Search procedure in TEA576X.cpp
Please download all those files again!



TEA576X
Recall that the chips of the family TEA576X differ only for the communication protocol (SPI or I2C). We have therefore conceived an abstract class, TEA576X, which implements all the methods except the write and read functions that are delegated to the derived classes. Both the header and the implementation files are pretty long, you can download them below:

The headers
Choose the header you need for your sketches. Save these files as ClassName.h

Class TEA5767HL
/**
 *  \file TEA5767HL.h
 *
 *  \brief A class for dealing with TEA5767HL chip.
 *
 *  \author Enrico Formenti
 *  \date 23 dec 2014
 *  \version 1.0
 *
 *  \copyright BSD license, check the License page on the blog for more information
 *  All this text must be included in any redistribution.
 *  <br><br>
 *  See macduino.blogspot.com for more details.
 */

#ifndef ____TEA5767HL__
#define ____TEA5767HL__

#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif


#include "TEA576X.h"
#include <SPI.h>

#define M_FM_TEA5767HL 0xC8189CB3

/**
 \class TEA5767HL TEA5767HL.h
 \brief A class for TEA5767HL component.
 
 This class implements the methods to interact with the TEA5767HL component
 which is a FM receiver. For more on this component refer to
 http://macduino.blogspot.com/2014/12/FM-Radio-TEA5767.html
 
 \see TEA576X
 */

class TEA5767HL : public TEA576X {
private:
    /**
     * \var _SSPin
     * \brief Slave Select pin for the SPI protocol.
     */
    uint8_t _SSPin; // Slave Select pin
public:
    /**
        \fn void begin(float xtal, uint8_t SSpin)
        \brief Init TEA5767HL chip.
        @param SSpin Slave Select pin.
    */
    void begin(float xtal, uint8_t SSpin);
    /**
     \fn void write()
     \brief Send the current write sequence to the TEA5767HL.
     \warning All the operations or changes to the module settings have no effect
     untill a write() operation is issued.
     */
    void write();
    /**
     \fn void read()
     \brief Read-in the current read sequence of the TEA5767HL.
     */
    void read();
};


#endif /* defined(____TEA5767HL__) */
Class TEA5768HL
/**
 *  \file TEA5768HL.h
 *
 *  \brief A class for dealing with TEA5768HL chip.
 *
 *  \author Enrico Formenti,
 *  \date 23 dec 2014
 *  \version 1.0
 *
 *  \copyright BSD license, check the License page on the blog for more information. All this text must be 
 *  included in any redistribution.
 *  <br><br>
 *  See macduino.blogspot.com for more details.
 */

#ifndef ____TEA5768HL__h
#define ____TEA5768HL__h

#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include "TEA576X.h"
#include <Wire.h>

#define M_FM_TEA5767HL 0x717D6A52

/**
 \class TEA5768HL TEA5768HL.h
 \brief A class for TEA5768HL component.
 
 This class implements the methods to interact with the TEA5768HL component
 which is a FM receiver. For more on this component refer to
 http://macduino.blogspot.com/2014/12/FM-Radio-TEA5767.html
 
 \see TEA576X
 */

class TEA5768HL : public TEA576X {
public:
    /**
     \fn void write()
     \brief Send the current write sequence to the TEA5768HL.
     \warning All the operations or changes to the module settings have no effect
     untill a write() operation is issued.
     */
    voidwrite
Class TEA5767HN

Warning: If you have installed Arduino 1.5.8 Beta, then you need to install SPI library manually from GitHub. It can be found here. If you have an older version (1.0.6 for example) then there is no problem since it comes with the SPI library pre-installed.

Implementing the classes
Choose the files you need for your sketches and save the files as ClassName.cpp


Implementation of the class TEA5767HL
/**
 *  \file TEA5767HL.cpp
 *
 *  \brief Implementation of a class for dealing with TEA5767HL chip.
 *
 *  \author Enrico Formenti
 *  \date 23 dec 2014
 *  \version 1.0
 *
 *  \copyright BSD license, check the License page on the blog for more information
 *  All this text must be included in any redistribution.
 *  <br><br>
 *  See macduino.blogspot.com for more details.
 */

#include "TEA5767HL.h"

void TEA5767HL::begin(float xtal, uint8_t SSpin) {
    TEA576X::begin(xtal);
    _SSPin = SSpin;
}

void TEA5767HL::write() {
    register uint8_t i;
    
    // take the SS pin low to select the chip:
    digitalWrite(_SSPin,LOW);
    
    // send buffer data
    for(i=0; i<5; i++)
        SPI.transfer(wbuf[i]);

    // take the SS pin high to de-select the chip:
    digitalWrite(_SSPin,HIGH);
}

void TEA5767HL::read() {
    register uint8_t i;
    
    // take the SS pin low to select the chip:
    digitalWrite(_SSPin,LOW);
    
    // read-in buffer data
    for(i=0; i<5; i++)
        rbuf[i] = SPI.transfer(0x0);
    
    // take the SS pin high to de-select the chip:
    digitalWrite(_SSPin,HIGH);
}
Implementation of the class TEA5768HL
/**
 *  \file TEA5768HL.cpp
 *
 *  \brief Implementation of a class for dealing with TEA5768HL chip.
 *
 *  \author Enrico Formenti
 *  \date 23 dec 2014
 *  \date 22 jan 2015
 *  \version 1.1
 *  \copyright BSD license, check the License page on the blog for more information
 *  All this text must be included in any redistribution.
 *  <br><br>
 *  See macduino.blogspot.com for more details.
 */

#include "TEA5768HL.h"

void TEA5768HL::write() {
    register uint8_t i;
    
    Wire.beginTransmission(TEA576X_I2C_ADDRESS);
    
    for(i=0; i<5; i++)
        Wire.write(wbuf[i]);
    
    Wire.endTransmission();
}

void TEA5768HL::read() {
    register uint8_t i = 0;
    
    Wire.requestFrom(TEA576X_I2C_ADDRESS, 5);
    
    while(Wire.available())
        rbuf[i++] = Wire.read();
}
Implementation of the class TEA5767HN
/**
 *  \file TEA5767HN.cpp
 *
 *  \brief Implementation of a class for dealing with TEA5767HN chip.
 *
 *  \author Enrico Formenti
 *  \date 23 dec 2014
 *  \date 22 jan 2015
 *  \version 1.1
 *  \copyright BSD license, check the License page on the blog for more information
 *  All this text must be included in any redistribution.
 *  <br><br>
 *  See macduino.blogspot.com for more details.
 */

#include "TEA5767HN.h"

void TEA5767HN::begin(float xtal, bool bus, uint8_t SSpin) {
    _bustype = bus;
    _SSPin = SSpin;
    TEA576X::begin(xtal);
}

void TEA5767HN::write() {
    register uint8_t i;
    
    if(_bustype) {
        // take the SS pin low to select the chip:
        digitalWrite(_SSPin,LOW);
    
        // send buffer data
        for(i=0; i<5; i++)
            SPI.transfer(wbuf[i]);

        // take the SS pin high to de-select the chip:
        digitalWrite(_SSPin,HIGH);
    }
    else {
        Wire.beginTransmission(TEA576X_I2C_ADDRESS);
        
        for(i=0; i<5; i++)
            Wire.write(wbuf[i]);
        
        Wire.endTransmission();

    }
}

void TEA5767HN::read() {
    register uint8_t i = 0;

    if(_bustype) {
        // take the SS pin low to select the chip:
        digitalWrite(_SSPin,LOW);
    
        // read-in buffer data
        for(; i<5; i++)
            rbuf[i] = SPI.transfer(0x0);
    
        // take the SS pin high to de-select the chip:
        digitalWrite(_SSPin,HIGH);
    }
    else {
        
        Wire.requestFrom(TEA576X_I2C_ADDRESS, 5);
        
        while(Wire.available())
            rbuf[i++] = Wire.read();
    }
}

The sketch
In order to test the the above classes here is a simple sketch. To run the sketch you need the files TEA5767.* (see above), TEA5767HN.* (see above) and, of course, a TEA5767 FM module (see Figure 2 in this post). The sketch initialises the TEA5767HN and then search for a station. If one is found then the module is tuned at this frequency. Pay attention that by default the tuner uses the US/European FM band (87.5-108MHz), if you need the Japanese FM band (76-91MHz), then you should add the following instruction after tea.begin(...);:
tea.setBandLimits(JAPANESE_FM_BAND);

The sketch TEA5767HN-test.ino
/**
 *  \file TEA5767HN-test.ino
 *
 *  \brief A quick example for testing the TEA5767HN chip.
 *
 *  \author Enrico Formenti
 *  \date 27 dec 2014
 *  \version 1.0
 *  \copyright BSD license, check the License page on the blog for more information. All this text must be 
 *  included in any redistribution.
 *  <br><br>
 *  See macduino.blogspot.com for more details.
 */
 
#include "TEA5767HN.h"

TEA5767HN tea;

void setup() {
  Serial.begin(9600);
  
  tea.begin(TEA576X_XTAL_32768Hz, TEA5767HN_I2CBUS);
  
  if(!tea.search(SEARCH_DIR_FORWARD, SEARCH_LEV_MEDIUM)) {
    Serial.print("Couldn't find any station!");
  }
  else {
    Serial.print("Playing station at ");
    Serial.print(tea.getFrequency()/1000000.0);
    Serial.print("MHz");
  }
}

void loop() {
  // nothing to do at present...
}
To run this sketch you need:
  • 1x Arduino Uno (or one of his brothers)
  • 1x TEA5767HN chip
  • 1x louspeaker 4Ω 1/4 Watt (or similar)
  • 7x Dupont connection cables
  • 1x long enough cable for the antenna (more details here)
Figure 1. shows how to connect the material. Remark that the output level of the module is very weak. This is the reason for which one finds many modules that adds to TEA5767HN an amplification stage, like the one that we will see in the next post.


Figure 1. Basic connections for the TEA5767HN module.



What's next
As promised in the abstract we will provide a class for dealing with the FM module and finally an application example building a simple FM radio player front-end.

See also
FM Radio receiver (TEA5767HL-TEA5767HN-TEA5768HL) - Part 1
FM Radio receiver (TEA5767HL-TEA5767HN-TEA5768HL) - Part 3
FM Radio receiver (TEA5767HL-TEA5767HN-TEA5768HL) - Part 4

1 comment :