28 October 2014

An Arduino library for FM radio chips

My latest project is about controlling an FM radio chip by using an Arduino Board, an LCD display and a rotary encoder all the components I need to build a standalone radio for my needs.

There are diverse radio chips available for building radio receivers. Because most of them are made for integration into mobile phones or car radios they normally come on breakout boards, sometimes together with audio amplifiers for headphones.

The ones I found and tried are:

  • The SI4703 from Silicon Labs
  • RDA5807 from RDA Microelectronics
  • TEA5767 from NXP

    They all are capable for receiving FM radio stations in stereo with European and US settings and can be controlled by using the I2C bus. However there are differences in the sensitivity and quality and well on receiving RDS information from the stations.

    The idea of the project beside implementing a radio for my personal needs is to provide Arduino compatible libraries for these (and possible more) chips that all offer the same functionality and expose the same functions. These radio chip adaptions can be combined with the also available RDS encoder and the radio applications.

    This is my current hardware setup for the latest project I am working on by using a breakout board for the SI4703 chip including an audio amplifier that I found on eBay:

    SAM_2504

    The radio library

    The libraries for this project can be found on github:

    https://github.com/mathertel/Radio

    You can download all the files at once by using the provided zip file:

    https://github.com/mathertel/Radio/archive/master.zip

    I still work on this and still some features I like to implement are still in development but maybe you already have experiences with audio functionality on the Arduino or other platforms or you also work on a similar project. Let me know (via eMail) and maybe we can share some experiences.

    Open Topics

    • Implementing all functions for all chips
    • good documentation
    • pictures
    • writing about using LCD displays in the I2C bus
    • writing about interpreting RDS data
    • … let me know
  • 19 October 2014

    Joystick shields for Arduino

    I was playing around lately with some standard I/O boards and came across the joystick shields. There are at least 2 versions of joystick shields on the market. There is one from sparkfun (see link below) and another labeled with funduino that is available in many stores and as well on eBay.

    Both share a kind of Nintendo layout using an analog joystick on the left, 4 buttons on the right and 2 buttons in between. The JoyStick Shield V1.a is the one I like to write bout here but I expect that the sources I share with you can help out on other layouts too.

    JoyStickShield

    The Funduino version has more functionality by providing  switch for the reference voltage of the analog joystick and a lot of connectors especially for the NRF24L01 transceiver. However samples for the shield are hard to find and most stores don’t provide a schema. So here is my documentation that may help you out of this and some sketches to show the functionality.

    The JoyStick IO definitions I use are for the Funduino JoyStick Shield V1.A but they can easily be adapted to the sparkfun and other similar joystick shields.

    Raw Signal testing

    The JoyStick_RawTest.ino sketch that you can find in the library shows how to initialize all the input ports of the Arduino corresponding to the buttons and the joystick of the shield.

    Here is the list of the Arduino ports used by the shield buttons and joystick:

    function io port
    Button A digital pin 2
    Button B digital pin 3
    Button C digital pin 4
    Button D digital pin 5
    Button E digital pin 6
    Button F digital pin 7
    X - Axis analog pin A0
    Y – Axis analog pin A1
    Joystick push, Button K digital pin 8

    In the loop function the real raw signal levels of the IO are printed out to the Serial port so you can inspect the current values. After compiling and uploading the sketch you should open the serial monitor with the 57600 baud settings and watch all the information coming from the shield.
    You can see the difference for the 3V3 / 5V switch in the possible values of the analog input signals.

    You should use this sketch just to be sure all the IO definitions are fine.

    Signal testing

    However, using the raw signals is a kind of pain. 2 simple methods can help you to make this more easy. The JoyStick_Test.ino sketch that you can find in the download files shows how to use the input on a more logical level and in respect of the not so exact analog joystick signals.

    Buttons

    The levels of the buttons are on the level 1 when not pressed. The conversion is implemented in the function joyButton(...) and returns a boolean value.

    boolean joyButton(byte pin) {
      int signal = digitalRead(pin);
      return (signal == 0);
    } // joyButton

    JoyStick position

    The levels of the X and Y joystick normally are not very correct. If you leave the stick untouched in the middle position the actual value from the analog port will not be exactly half the reference voltage and it may jump between some values. It is also very hard to get the stick to a specific position and hold it in place. Therefore I use a function that converts to the analog input value to a range of -4 to 4 where 0 is the level in normal position. The conversion is implemented in the function joyStick(...) and returns a signed int. The 3v3 / 5v switch should be in the 5v position.

    int joyStick(byte pin) {
      // read the analog value
      int signal = analogRead(pin);
      // convert with mathematics:
      signal = ((signal+64) / 128) - 4;
      return (signal);
    } // joyStick

    After compiling and uploading the sketch you should open the serial monitor with the 57600 baud settings and watch all the information coming from the shield.

    If you like to use these functions just copy them over to your sketch.

    ...

    Sketch JoyStick_RawTest.ino

    /// \file JoyStick_rawtest.ino
    /// \brief A simple sketch showing the binary input values fro the joystick board.
    ///
    /// \author Matthias Hertel, http://www.mathertel.de
    /// \copyright Copyright (c) 2014 by Matthias Hertel.\n
    /// This work is licensed under a BSD style license.\n
    /// See http://www.mathertel.de/License.aspx
    ///
    /// \details
    /// This sketch shows how to initialize all the input ports of the Arduino
    /// corresponding to the buttons and the joystick of the shield.
    /// The real raw singal levels of the IO are printed out to the Serial port
    /// so you can inspect the current values.
    /// you can see the difference for the 3V3 / 5V switch in the possible values
    /// of the analog input signals.
    /// The JoyStick IO definitions  here are for the Funduino JoyStick Shield V1.A.
    /// It can easily be adapted to the sparkfun JoyStick Shield.
    ///
    /// More documentation and source code is available at http://www.mathertel.de/Arduino
    ///
    /// History:
    /// --------
    /// * 18.10.2014 creation.
    
    /// Port definitions for the buttons on the shield with the printed labels
    #define BUTTON_A  2 
    #define BUTTON_B  3
    #define BUTTON_C  4
    #define BUTTON_D  5
    #define BUTTON_E  8
    #define BUTTON_F  7
    
    /// Port definitions for the JoyStick functions
    #define ANALOG_PUSH 8
    #define ANALOG_X A0 
    #define ANALOG_Y A1 
    
    
    void setup() {
      Serial.begin(57600);
    
      // Setup button inputs with internal pull up high resistor
      pinMode(BUTTON_A, INPUT_PULLUP);
      pinMode(BUTTON_B, INPUT_PULLUP);
      pinMode(BUTTON_C, INPUT_PULLUP);
      pinMode(BUTTON_D, INPUT_PULLUP);
      
      // Setup the option buttons
      pinMode(BUTTON_E, INPUT_PULLUP);
      pinMode(BUTTON_F, INPUT_PULLUP);
      
      // Setup joystick button
      pinMode(ANALOG_PUSH, INPUT_PULLUP);
      // The analog inputs need no setup.
    }
    
    void loop() {
      Serial.print(" A:"); Serial.print(digitalRead(BUTTON_A));
      Serial.print(" B:"); Serial.print(digitalRead(BUTTON_B));
      Serial.print(" C:"); Serial.print(digitalRead(BUTTON_C));
      Serial.print(" D:"); Serial.print(digitalRead(BUTTON_D));
    
      Serial.print(" E:"); Serial.print(digitalRead(BUTTON_E));
      Serial.print(" F:"); Serial.print(digitalRead(BUTTON_F));
      
      Serial.print(" -- X:"); Serial.print(analogRead(ANALOG_X));
      Serial.print(" y:"); Serial.print(analogRead(ANALOG_Y));
      Serial.print(" K:"); Serial.print(digitalRead(ANALOG_PUSH));
    
      Serial.println();
      delay(250);
    }
    

     

    Sketch JoyStick_Test.ino

    ///
    /// \file JoyStick_Test.ino
    /// \brief A simple sketch showing the binary input values from the joystick board.
    ///
    /// \author Matthias Hertel, http://www.mathertel.de
    /// \copyright Copyright (c) 2014 by Matthias Hertel.\n
    /// This work is licensed under a BSD style license.\n
    /// See http://www.mathertel.de/License.aspx
    ///
    /// \details
    /// This sketch shows how to initialize all the input ports of the Arduino
    /// corresponding to the buttons and the joystick of the shield.
    /// Here the io signal are converted to be interpreted easily:
    /// * The levels of the buttons are on the level 1 when not pressed.
    /// The conversion is implemented in the function joyButton(...) and returns a boolean value.
    /// * The levels of the X and Y joystick normally are not very correct.
    /// They are converted to the range -4 to 4 where 0 is the level in normal position.
    /// The conversion is implemented in the function joyStick(...) and returns a signed int.
    /// The 3v3 / 5v switch should be in the 5v position.
    ///
    /// The JoyStick IO definitions  here are for the Funduino JoyStick Shield V1.A.
    /// It can easily be adapted to the sparkfun JoyStick Shield.
    ///
    /// More documentation and source code is available at http://www.mathertel.de/Arduino
    ///
    /// History:
    /// --------
    /// * 18.10.2014 creation.
    
    /// Port definitions for the buttons on the shield with the printed labels
    #define BUTTON_A  2 
    #define BUTTON_B  3
    #define BUTTON_C  4
    #define BUTTON_D  5
    #define BUTTON_E  8
    #define BUTTON_F  7
    
    /// Buttons with the names of the classic Nintendo layout
    #define BUTTON_SELECT BUTTON_F
    #define BUTTON_START BUTTON_E
    
    /// Port definitions for the JoyStick functions
    #define ANALOG_PUSH 8
    #define ANALOG_X A0 
    #define ANALOG_Y A1 
    
    boolean joyButton(byte pin) {
      int signal = digitalRead(pin);
      return (signal == 0);
    } // joyButton
    
    
    int joyStick(byte pin) {
      // 000....128....256....384....512....640....768....896....1024
      // -4     -3     -2     -1      0      1      2      3       4
      int signal = analogRead(pin);
      /// convert with mathematics
      signal = ((signal+64) / 128) - 4;
      return (signal);
    } // joyStick
    
    
    void setup() {
      Serial.begin(57600);
    
      // Setup button inputs with internal pull up high resistor
      pinMode(BUTTON_A, INPUT_PULLUP);
      pinMode(BUTTON_B, INPUT_PULLUP);
      pinMode(BUTTON_C, INPUT_PULLUP);
      pinMode(BUTTON_D, INPUT_PULLUP);
      
      // Setup the option buttons
      pinMode(BUTTON_E, INPUT_PULLUP);
      pinMode(BUTTON_F, INPUT_PULLUP);
      
      // Setup joystick button
      pinMode(ANALOG_PUSH, INPUT_PULLUP);
      // The analog inputs need no setup.
    }
    
    void loop() {
      Serial.print(" A:"); Serial.print(joyButton(BUTTON_A));
      Serial.print(" B:"); Serial.print(joyButton(BUTTON_B));
      Serial.print(" C:"); Serial.print(joyButton(BUTTON_C));
      Serial.print(" D:"); Serial.print(joyButton(BUTTON_D));
    
      Serial.print(" E:"); Serial.print(joyButton(BUTTON_E));
      Serial.print(" F:"); Serial.print(joyButton(BUTTON_F));
      
      Serial.print(" -- X:"); Serial.print(joyStick(ANALOG_X));
      Serial.print(" y:"); Serial.print(joyStick(ANALOG_Y));
      Serial.print(" K:"); Serial.print(joyButton(ANALOG_PUSH));
    
      Serial.println();
      delay(250);
    }
    

     

    Additional Links

    http://arduino.cc/en/Main/ArduinoBoardEsplora

    http://arduino.cc/en/Reference/EsploraReadJoystickSwitch