Arduino Si4735 radio library Si4735 library
Arduino and Silicon Laboratories Si4735 radio library
Brought to you by:
michael-kennedy
#LyX 2.2 created this file. For more info see http://www.lyx.org/ \lyxformat 508 \begin_document \begin_header \save_transient_properties true \origin unavailable \textclass article \begin_preamble \input{lyx_preamble} \end_preamble \use_default_options false \begin_modules fixltx2e \end_modules \maintain_unincluded_children false \language english \language_package default \inputencoding auto \fontencoding global \font_roman "palatino" "default" \font_sans "cmss" "default" \font_typewriter "courier" "default" \font_math "auto" "auto" \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 100 \font_tt_scale 100 100 \graphics default \default_output_format pdf2 \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref true \pdf_bookmarks true \pdf_bookmarksnumbered true \pdf_bookmarksopen true \pdf_bookmarksopenlevel 4 \pdf_breaklinks true \pdf_pdfborder true \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle true \pdf_quoted_options "urlcolor=blue" \papersize letterpaper \use_geometry true \use_package amsmath 1 \use_package amssymb 1 \use_package cancel 1 \use_package esint 1 \use_package mathdots 1 \use_package mathtools 1 \use_package mhchem 1 \use_package stackrel 1 \use_package stmaryrd 1 \use_package undertilde 1 \cite_engine basic \cite_engine_type default \biblio_style plain \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \justification true \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \paperwidth 210mm \paperheight 11in \leftmargin 3cm \topmargin 2cm \rightmargin 2cm \bottommargin 2cm \secnumdepth 2 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \html_math_img_scale 3 \end_header \begin_body \begin_layout Title Library for Silicon Laboratories Si4735 radio receiver chip and an Arduino microcontroller \end_layout \begin_layout Author Copyright 2012, 2013, 2015, 2018 Michael J. Kennedy \end_layout \begin_layout Standard This program is free software: you can redistribute it and\SpecialChar breakableslash or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. To view a copy of the GNU Lesser General Public License, visit these two web pages: \end_layout \begin_layout Quote \begin_inset Flex URL status open \begin_layout Plain Layout http://www.gnu.org/licenses/gpl-3.0.html \end_layout \end_inset \end_layout \begin_layout Quote \begin_inset Flex URL status open \begin_layout Plain Layout http://www.gnu.org/licenses/lgpl-3.0.html \end_layout \end_inset \end_layout \begin_layout Standard This software can be found at the following web site: \end_layout \begin_layout Quote \begin_inset Flex URL status open \begin_layout Plain Layout https://sourceforge.net/projects/arduino-si4735/files/ \end_layout \end_inset \end_layout \begin_layout Standard The Mercurial repository can be downloaded with the following shell command: \end_layout \begin_layout LyX-Code hg clone http://hg.code.sf.net/p/arduino-si4735/si4735 Si4735 \end_layout \begin_layout Standard To report bugs or make suggestions contact me at: \end_layout \begin_layout Quote michael.joseph.kennedy.1970 [_a_t_] gmail [dot] com \end_layout \begin_layout Standard This library is a fork of previous libraries. Older versions can be found here: \end_layout \begin_layout Itemize Ryan Owens, \begin_inset Flex URL status open \begin_layout Plain Layout https://www.sparkfun.com/products/10342 \end_layout \end_inset \end_layout \begin_layout Itemize Wagner Sartori Junior, \begin_inset Flex URL status open \begin_layout Plain Layout https://github.com/trunet/Si4735 \end_layout \end_inset \end_layout \begin_layout Itemize Jon Carrier, \begin_inset Flex URL status open \begin_layout Plain Layout https://github.com/jjcarrier/Si4735 \end_layout \end_inset \end_layout \begin_layout Standard \series bold \begin_inset Box Shadowbox position "t" hor_pos "c" has_inner_box 1 inner_pos "t" use_parbox 0 use_makebox 0 width "100col%" special "none" height "1in" height_special "totalheight" thickness "0.4pt" separation "3pt" shadowsize "4pt" framecolor "black" backgroundcolor "none" status open \begin_layout Description \series bold Warning: This library is \bar under not \bar default completely compatible with these other versions of the library! Most importantl y, usage of begin() has been changed. \series default \series bold \emph on \bar under You MUST change your code! If you don't, the program will still compile, but fail to work correctly! \series default \emph default \bar default See \begin_inset CommandInset ref LatexCommand formatted reference "sec:Initializing-the-radio" \end_inset \begin_inset Quotes eld \end_inset \begin_inset CommandInset ref LatexCommand nameref reference "sec:Initializing-the-radio" \end_inset \begin_inset Quotes erd \end_inset below for further details. \end_layout \end_inset \end_layout \begin_layout Standard This library can be used with the following SparkFun boards: \end_layout \begin_layout Itemize DEV-10342, \begin_inset Quotes eld \end_inset SI4735 AM & FM Receiver Shield, \begin_inset Quotes erd \end_inset \begin_inset Flex URL status open \begin_layout Plain Layout http://www.sparkfun.com/products/10342 \end_layout \end_inset \end_layout \begin_layout Itemize WRL-10906, \begin_inset Quotes eld \end_inset Si4735 FM/AM Radio Receiver Breakout, \begin_inset Quotes erd \end_inset \begin_inset Flex URL status open \begin_layout Plain Layout http://www.sparkfun.com/products/10906 \end_layout \end_inset \end_layout \begin_layout Standard Both contain a Si4735-C40 radio receiver chip. The library was tested with a shield marked on the bottom with a date of \begin_inset Quotes eld \end_inset 4\SpecialChar breakableslash 14\SpecialChar breakableslash 11. \begin_inset Quotes erd \end_inset \end_layout \begin_layout Standard The Si4735 supports all modes available in the Si47xx family except for Weather Band (WB) receive and FM transmit. As a result, most chips in this family can be used with this library, if you are careful to not access missing modes. In some cases, small modifications to the library may be needed for full compatibility. Note: We do not yet support the auxiliary input mode found on the Si4735-D60 or later. Also note: The Si4700\SpecialChar breakableslash 01\SpecialChar breakableslash 02\SpecialChar breakableslash 03\SpecialChar breakableslash 08\SpecialChar breakableslash 09 chips are older and use a completely different command syntax. Therefore, they cannot be used with this library. \end_layout \begin_layout Standard This library supports all current Arduinos including the 2009 (Duemilanove), Uno, Mega, Mega 2560, Leonardo, and Due. \end_layout \begin_layout Standard To understand how to use this library, you \series bold MUST \series default read this document and the \family sans Si4735.h \family default file. You should also read through the example applications found in the \family sans examples \family default directory. It will also be helpful to read the comments in the source code. Everything has been heavily commented to make understanding and customizing the library easy. \end_layout \begin_layout Standard \series bold \begin_inset Box Shadowbox position "t" hor_pos "c" has_inner_box 1 inner_pos "t" use_parbox 0 use_makebox 0 width "100col%" special "none" height "1in" height_special "totalheight" thickness "0.4pt" separation "3pt" shadowsize "4pt" framecolor "black" backgroundcolor "none" status open \begin_layout Description Warning: If you are going to either view or edit the library's source code or the \family sans Changes.text \family default file, you \series bold \bar under MUST \series default \bar default use a \series bold \bar under programmer's text editor \series default \bar default . I recommend one of the following, multi-platform editors: \end_layout \begin_deeper \begin_layout Itemize Geany: \begin_inset Flex URL status open \begin_layout Plain Layout http://www.geany.org/ \end_layout \end_inset \end_layout \begin_layout Itemize SciTE: \begin_inset Flex URL status open \begin_layout Plain Layout http://www.scintilla.org/SciTE.html \end_layout \end_inset \end_layout \end_deeper \end_inset \end_layout \begin_layout Description Note: I have not yet tested the Arduino Due code because I do not currently have this board. \end_layout \begin_layout Description Note: I have not yet tested the I2C code because the Si4735 shield I used for testing does not permit using I2C. Also, I do not currently have the breakout board which can use I2C. \end_layout \begin_layout Standard \begin_inset Newpage newpage \end_inset \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \begin_inset Newpage newpage \end_inset \end_layout \begin_layout Section Background information \end_layout \begin_layout Standard For more information on the Silicon Labs Si4735, see the following documents. (Check SparkFun and Silicon Labs web sites.): \end_layout \begin_layout Itemize Data sheet: Si4734\SpecialChar breakableslash 35-C40 — Gives hardware description. (Get version on SparkFun web site.) \end_layout \begin_layout Itemize Application Note: AN332: \begin_inset Quotes eld \end_inset Si47xx Programming Guide \begin_inset Quotes erd \end_inset — Explains the Si4735 (and similar chips) from a software perspective. \end_layout \begin_deeper \begin_layout Standard Warning: The \begin_inset Quotes eld \end_inset Si47xx Programming Guide \begin_inset Quotes erd \end_inset implies that each command returns a status byte with the current interrupts. However, in most cases, the status byte contains random garbage. The exceptions are: \end_layout \begin_layout Itemize The CTS interrupt is always up-to-date. The radio chip always updates the CTS bit in the status byte whenever the CTS interrupt changes. Therefore, you can always get the current status of CTS by reading the status byte, regardless of the previous command sent. \end_layout \begin_layout Itemize A few commands return a status byte with their interrupt updated: \end_layout \begin_deeper \begin_layout Quote \begin_inset Tabular <lyxtabular version="3" rows="4" columns="2"> <features tabularvalignment="middle"> <column alignment="left" valignment="top"> <column alignment="center" valignment="top"> <row> <cell alignment="left" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold Command \end_layout \end_inset </cell> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold Interrupt \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout TUNE_STATUS \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout STC \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout RSQ_STATUS \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout RSQ \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout RDS_STATUS \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout RDS \end_layout \end_inset </cell> </row> </lyxtabular> \end_inset \end_layout \end_deeper \begin_layout Itemize When an interrupt pulse is received by the Arduino, the only way to accurately know the status of the non CTS interrupts is to send the GET_INT_STATUS command and then read its status byte. \end_layout \end_deeper \begin_layout Itemize Application Note: AN383: \begin_inset Quotes eld \end_inset Si47xx Antenna, Schematic, Layout, and Design Guidelines \begin_inset Quotes erd \end_inset — Gives important information on designing antennas for the radio. Please note that the Si4735 shield is based on the design given in section 10 \begin_inset Quotes eld \end_inset Whip Antenna for SW Receive on AMI \begin_inset Quotes erd \end_inset (page 46 in revision 0.6.) \end_layout \begin_layout Section Using the SparkFun Si4735 Arduino Shield \end_layout \begin_layout Standard The SparkFun Si4735 Arduino Shield requires modification to work correctly: \end_layout \begin_layout Itemize There is no voltage level shifting on Si4735's GPO1 (MISO) and GPO2 (INT) outputs. The Si4735 must run at 3.3 V while most Arduinos run at 5 V. The shield converts all Arduino outputs to 3.3 V logic levels but does nothing to the Si4735 outputs. This is a problem because, when running at 5 V, an input must reach 3 V for the AVR to treat it as high (V \begin_inset script subscript \begin_layout Plain Layout IH \end_layout \end_inset ): \end_layout \begin_deeper \begin_layout Quote \begin_inset Formula $V_{CC}\times.6=5V\times.6=3V$ \end_inset \end_layout \begin_layout Standard However, the minimum guaranteed output voltage for a high signal from the Si4735 radio chip is (V \begin_inset script subscript \begin_layout Plain Layout OH \end_layout \end_inset ): \end_layout \begin_layout Quote \begin_inset Formula $V_{IO}\times.8=3.3V\times.8=2.64V$ \end_inset \end_layout \begin_layout Standard Because the radio chip's output for a high signal can be less than the 3 V required by the AVR, either some form of level shifting from 3.3 V to 5 V must be added or an Arduino running at 3.3 V must be used. 3.3 V Arduinos include the Due, the 3.3 V versions of the Pro and Pro Mini from SparkFun, and the Seeeduino set to run at 3.3 V. \end_layout \begin_layout Standard See \begin_inset CommandInset ref LatexCommand formatted reference "sec:Level-shifting" \end_inset \begin_inset Quotes eld \end_inset \begin_inset CommandInset ref LatexCommand nameref reference "sec:Level-shifting" \end_inset \begin_inset Quotes erd \end_inset below for more information. \end_layout \end_deeper \begin_layout Itemize The AREF pin is connected to ground on the shield's printed circuit board. AREF should never be grounded as this makes using the AVR's analog to digital converter impossible. Fixing this is optional if you do not need analog to digital conversion. However, you never know what changes you will make to your radio project in the future. \end_layout \begin_deeper \begin_layout Standard To fix this, you need to break the connection between the Arduino's AREF input and ground. Probably the best solution is to cut the eight tiny traces between the pad and ground plane with a sharp knife, X-Acto blade, or razor blade. There are four traces on each side of the circuit board. Do this before soldering a connector to the shield. \end_layout \begin_layout Standard Another option is to use a connector that does not connect the shield's AREF pad to the Arduino's AREF input. \end_layout \end_deeper \begin_layout Itemize The RF\SpecialChar breakableslash Antenna section is based on application note AN383, section 10 \begin_inset Quotes eld \end_inset Whip Antenna for SW Receive on AMI, \begin_inset Quotes erd \end_inset page 46 in revision 0.6. However, there is one small difference: The application note shows a connection between the other pin of the double throw switch and the AM loop antenna. This shorts out the 33 pF capacitor when the switch is in AM mode. SparkFun omitted this connection. Fixing this mistake is only needed for AM Medium Wave (common AM service) and Long Wave reception. However, if you do fix it, it should improve AM Medium Wave reception. On my board, RSSI (signal strength) went up by 5. \end_layout \begin_deeper \begin_layout Standard Note: The switch is mislabeled by SparkFun as \begin_inset Quotes eld \end_inset AM\SpecialChar breakableslash LW \begin_inset Quotes erd \end_inset and \begin_inset Quotes eld \end_inset FM\SpecialChar breakableslash SW. \begin_inset Quotes erd \end_inset It should be labeled as \begin_inset Quotes eld \end_inset FM\SpecialChar breakableslash AM\SpecialChar breakableslash LW \begin_inset Quotes erd \end_inset and \begin_inset Quotes eld \end_inset SW. \begin_inset Quotes erd \end_inset \end_layout \end_deeper \begin_layout Section Using the SparkFun Si4735 shield with various Arduinos \end_layout \begin_layout Standard The SparkFun Si4735 shield only supports the \begin_inset Quotes eld \end_inset original \begin_inset Quotes erd \end_inset Arduinos usually based on the ATMega328P including the 2009 (Duemilanove), Uno, and their clones. The problem is that the Mega, Leonardo, and Due have their SPI port located on different pins than the shield. As a result, you cannot plug the shield into these Arduinos. Instead, you must use wires and connectors to build a custom cable between these Arduinos and the shield. \end_layout \begin_layout Standard The pin assignments for the SPI port can be found in Table \begin_inset CommandInset ref LatexCommand ref reference "tab:SPI-pin-assignments" \end_inset . \begin_inset Float table placement H wide false sideways false status open \begin_layout Plain Layout \noindent \align center \begin_inset Tabular <lyxtabular version="3" rows="5" columns="5"> <features tabularvalignment="middle"> <column alignment="left" valignment="top" width="0pt"> <column alignment="center" valignment="bottom" width="0pt"> <column alignment="center" valignment="bottom" width="0pt"> <column alignment="center" valignment="bottom" width="0pt"> <column alignment="center" valignment="bottom" width="0pt"> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold Shield \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold Mega \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold Leonardo \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold Due \end_layout \end_inset </cell> </row> <row> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold Name \end_layout \end_inset </cell> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold Pin \end_layout \end_inset </cell> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold Pin \end_layout \end_inset </cell> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold Pin \end_layout \end_inset </cell> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold Pin \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout MOSI \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 11 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 51 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 16 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 75 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout MISO \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 12 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 50 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 14 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 74 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout SCK \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 13 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 52 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 15 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 76 \end_layout \end_inset </cell> </row> </lyxtabular> \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout Pin assignments for the SPI port \begin_inset CommandInset label LatexCommand label name "tab:SPI-pin-assignments" \end_inset \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard On the Leonardo and Due, the MISO, SCK, and MOSI pins are only available on the ICSP connector. See: \begin_inset Flex URL status open \begin_layout Plain Layout http://arduino.cc/en/Reference/SPI \end_layout \end_inset . \end_layout \begin_layout Section Adapting the library to use the SparkFun Si4735 breakout board \end_layout \begin_layout Standard This library can be adapted to make use of all of the Si4735 breakout board's features by passing arguments to \family sans begin() \family default and \family sans setMode() \family default and occasionally by manually editing the top part of the \family sans Si4735.h \family default file. \end_layout \begin_layout Subsection Selecting SPI or I2C \end_layout \begin_layout Standard Unlike the Si4735 shield, the Si4735 breakout board can use either the SPI or I2C bus. By default, the library uses SPI. You can switch to I2C by commenting out the \begin_inset Quotes eld \end_inset \family typewriter #define Si47xx_SPI \family default \begin_inset Quotes erd \end_inset line by adding \begin_inset Quotes eld \end_inset \family typewriter // \family default \begin_inset Quotes erd \end_inset to the beginning like this: \end_layout \begin_layout LyX-Code //#define Si47xx_SPI \end_layout \begin_layout Standard Note: For your convenience, there are two versions of this library available for download. One for SPI users and one for I2C users. The only difference is the defining of the \family sans Si47xx_SPI \family default macro and which bus library the example programs include. \end_layout \begin_layout Standard The Si4735 has very specific power up requirements which the library will handle for you by controlling the radio's power and reset pins. By default, power is controlled by Arduino pin 8 and reset by Arduino pin 9. \end_layout \begin_layout Standard When powering up, the radio must be told to use SPI or I2C. No action is required to select I2C. To select SPI, the radio's interrupt (GPO2) pin must be driven high. This should be done with a 10 k \begin_inset Formula $\Omega$ \end_inset pull-up resistor connected between the radio's interrupt pin and 3.3 V. (Note that this is how the Si4735 shield selects SPI.) \end_layout \begin_layout Description Warning: I2C support requires version 1.0.0 or above of the Arduino development software. \end_layout \begin_layout Subsection \begin_inset CommandInset label LatexCommand label name "subsec:Configuring-SPI" \end_inset Configuring SPI \end_layout \begin_layout Standard The library defaults to Arduino pin 10 as the Slave Select (SS) for the radio's SPI port on all Arduinos. This assignment is arbitrary and can be changed in \family sans Si4735.h \family default by breakout board users. \end_layout \begin_layout Subsection \begin_inset CommandInset label LatexCommand label name "subsec:Configuring-interrupts" \end_inset Configuring interrupts \end_layout \begin_layout Standard By default, the library \emph on usually \emph default uses Arduino pin 2 as the interrupt input for compatibility with the Si4735 shield. However, you may change this by editing \family sans RADIO_INT_PIN \family default and \family sans RADIO_EXT_INT \family default in \family sans Si4735.h \family default . \end_layout \begin_layout Standard \family sans RADIO_INT_PIN \family default gives the Arduino pin number to use and \family sans RADIO_EXT_INT \family default gives the corresponding AVR interrupt number. When using an AVR based Arduino, if you change one of these, you \series bold \emph on must \series default \emph default change the other so that it matches Table \begin_inset CommandInset ref LatexCommand ref reference "tab:IRQ-Pin-to-IRQ-Num" \end_inset below! \end_layout \begin_layout Description Note: Pins 2 and 3 are used by the I2C port on the Leonardo. Because of this, when I2C is selected on the Leonardo, the interrupt input is moved to pin 7. \end_layout \begin_layout Standard Please note that ARM based Arduinos such as the Due do not use \family sans RADIO_EXT_INT \family default . Also, they can use any pin as the interrupt input. \end_layout \begin_layout Standard Each type of AVR based Arduino has its interrupt inputs on different pins. Table \begin_inset CommandInset ref LatexCommand ref reference "tab:IRQ-Pin-to-IRQ-Num" \end_inset gives the Arduino pin number ( \family sans RADIO_INT_PIN \family default ) and its corresponding AVR interrupt number ( \family sans RADIO_EXT_INT \family default ) for each type of Arduino board. \begin_inset Float table placement H wide false sideways false status open \begin_layout Plain Layout \noindent \align center \begin_inset Tabular <lyxtabular version="3" rows="15" columns="3"> <features tabularvalignment="middle"> <column alignment="left" valignment="top" width="0pt"> <column alignment="center" valignment="top" width="0pt"> <column alignment="center" valignment="top" width="0pt"> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold Arduino pin \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold AVR interrupt \end_layout \end_inset </cell> </row> <row> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold AVR based Arduino \end_layout \end_inset </cell> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold RADIO_INT_PIN \end_layout \end_inset </cell> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout \series bold RADIO_EXT_INT \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \begin_inset Quotes eld \end_inset Original, \begin_inset Quotes erd \end_inset \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout Uno, etc. \end_layout \end_inset </cell> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout 3 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout Mega, \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 21 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout Mega 2560 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 20 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 19 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 18 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 3 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 4 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset </cell> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout 3 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout 5 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout Leonardo \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 3 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 3 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 7 \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout 6 \end_layout \end_inset </cell> </row> </lyxtabular> \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout Mapping from AVR Interrupt Pin to Interrupt Number \begin_inset CommandInset label LatexCommand label name "tab:IRQ-Pin-to-IRQ-Num" \end_inset \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Description Warning: The AVR's hardware interrupt numbers for the Mega and Mega 2560 do \series bold not \series default match the interrupt numbers used when calling \family sans attachInterrupt() \family default ! Use the hardware interrupt numbers from the above table, not the interrupt numbers used with \family sans attachInterrupt() \family default ! \end_layout \begin_layout Standard Please note that pin 7 on the Leonardo is a valid interrupt input, despite the fact that \family sans attachInterrupt() \family default does not currently support it. \end_layout \begin_layout Subsection Configuring the radio's clock input \end_layout \begin_layout Standard If \family sans MODE_OPT_NO_XTAL \family default is passed to \family sans setMode() \family default , the library will set XOSCEN to false in ARG1 of the POWER_UP command. Otherwise, XOSCEN will be true in ARG1 of the POWER_UP command. \end_layout \begin_layout Standard \family sans MODE_OPT_NO_XTAL \family default should \emph on not \emph default be passed to \family sans setMode() \family default when a 32768 Hz crystal is attached to the radio's RCLK and GPO3 pins. (This is how the Si4735 shield and the Si4707 breakout board are setup. Therefore, users of these boards should call \family sans setMode() \family default without \family sans MODE_OPT_NO_XTAL \family default .) Other methods of supplying the radio with a clock signal should call \family sans setMode() \family default with \family sans MODE_OPT_NO_XTAL \family default . (For example, \family sans setMode(FM, MODE_OPT_NO_XTAL) \family default .) See the POWER_UP command in the \begin_inset Quotes eld \end_inset Si47xx Programming Guide \begin_inset Quotes erd \end_inset for more information on the XOSCEN argument. \end_layout \begin_layout Standard If you want digital audio output on the Si4735, you must generate a suitable clock signal for the radio and send it to the radio's RCLK or DCLK (GPO3) pin. You must also enable digital audio output by specifying the correct audio mode when calling \family sans setMode() \family default . See section 5.15 \begin_inset Quotes eld \end_inset Reference Clock \begin_inset Quotes erd \end_inset in the Si4735 data sheet and the REFCLK_FREQ and REFCLK_PRESCALE properties in the \begin_inset Quotes eld \end_inset Si47xx Programming Guide. \begin_inset Quotes erd \end_inset \end_layout \begin_layout Section \begin_inset CommandInset label LatexCommand label name "sec:Level-shifting" \end_inset Level shifting between 5 and 3.3 volts \end_layout \begin_layout Standard The Si4735 must run at 3.3 V or less. Most Arduinos run at 5 V. When using these Arduinos, level shifting is required. Level shifters work in either one direction (unidirectional) or in both directions (bidirectional). I2C requires a bidirectional shifter with open drain (open collector) outputs while SPI and the other I\SpecialChar breakableslash O signals only require a unidirectional shifter. \end_layout \begin_layout Description Warning: If the Arduino and radio chip will be sharing the SPI bus with other chips, then the radio's MISO pin (labeled GPO1 in the data sheet) requires a level shifter with a 3-state output. \end_layout \begin_layout Description Caution: All unused inputs on any chip should be connected to something to keep the chip stable and reduce power consumption. The three easiest ways to do this are to connect an unused input to either ground, the chip's power pin (labeled V \begin_inset script subscript \begin_layout Plain Layout DD \end_layout \end_inset or V \begin_inset script subscript \begin_layout Plain Layout CC \end_layout \end_inset ), or a pull-up resistor also connected to the chip's power pin. \end_layout \begin_layout Subsection Unidirectional level shifting from 5 to 3.3 volts \end_layout \begin_layout Standard This converts a high voltage (5 V) output from the Arduino to a low voltage (3.3 V) for the radio's input by using chips with high voltage tolerant inputs. \end_layout \begin_layout Itemize A simple and reliable high to low shifter is the 74HC4050 buffer gate. This is the shifter found on the SparkFun Si4735 shield. It can shift at least a 15 V signal to as little as 3 V. \end_layout \begin_deeper \begin_layout Standard To use this chip with the radio, connect the 74HC4050's power pin (labeled V \begin_inset script subscript \begin_layout Plain Layout DD \end_layout \end_inset or V \begin_inset script subscript \begin_layout Plain Layout CC \end_layout \end_inset ) to 3.3 V and the GND pin to ground. Then connect an Arduino output to a buffer gate's input. Finally, connect the gate's output to the radio's input. \end_layout \end_deeper \begin_layout Itemize A newer chip that can do high to low level shifting is the SN74LVC244 3-state buffer gate, which can shift from a maximum of 5.5 V down to as little as 1.65 V. As of this writing, this chip is available from Texas Instruments in DIP form. \end_layout \begin_deeper \begin_layout Standard To use this chip with the radio, connect the 74LVC244's power pin (labeled V \begin_inset script subscript \begin_layout Plain Layout DD \end_layout \end_inset or V \begin_inset script subscript \begin_layout Plain Layout CC \end_layout \end_inset ) to 3.3 V and the GND pin to ground. Then connect an Arduino output to a buffer gate's input. Finally, connect the gate's output to the radio's input. To make the 74LVC244 work, you must also enable its outputs by grounding its two Output Enable (1OE and 2OE) pins. \end_layout \end_deeper \begin_layout Subsection Unidirectional level shifting from 3.3 to 5 volts \end_layout \begin_layout Standard This converts a low voltage (3.3 V) output from the radio to a high voltage (5 V) for the Arduino's input. \end_layout \begin_layout Standard \begin_inset Box Shadowbox position "t" hor_pos "c" has_inner_box 1 inner_pos "t" use_parbox 0 use_makebox 0 width "100col%" special "none" height "1in" height_special "totalheight" thickness "0.4pt" separation "3pt" shadowsize "4pt" framecolor "black" backgroundcolor "none" status open \begin_layout Description DANGER: Other people's versions of this library (including the version from SparkFun) always seem to drive the INT (GPO2) and MISO (GPO1) pins high to select SPI mode. However, the data sheet clearly says you do not need to drive MISO high to select SPI. Also, driving INT high is unnecessary with the Si4735 shield because it includes a pull-up resistor on the radio's INT pin. This version of the library does not drive the INT or MISO pins high. If you use a unidirectional level shifter, then you \series bold \bar under MUST \series default \bar default either use this version of the library or modify the other version's source code to prevent driving these pins high. Otherwise, you will be temporarily connecting two outputs, which \series bold \bar under WILL \series default \bar default eventually damage your hardware! \end_layout \end_inset \end_layout \begin_layout Itemize Many years ago, it was common to mix CMOS and TTL families of chips. (Today, we only use CMOS.) Because these two families are incompatible, special versions of CMOS chips were made with TTL compatible inputs. The two most important families with this feature are named HCT and AHCT. Notice the \begin_inset Quotes eld \end_inset T \begin_inset Quotes erd \end_inset at the end of the names! The chips in these families accept an input of 2 V through 5 V as a valid high signal. As a result, these chips are ideal for level shifting from 3.3 V to 5 V. \end_layout \begin_deeper \begin_layout Standard Caution: Because the HCT and AHCT chips must have 5 V applied to their power pin (labeled V \begin_inset script subscript \begin_layout Plain Layout DD \end_layout \end_inset or V \begin_inset script subscript \begin_layout Plain Layout CC \end_layout \end_inset ), these chips can only be used when level shifting to 5 V. \end_layout \begin_layout Standard As mention above, the radio's MISO pin should have a level shifter with a 3-state output. A chip with that ability is the 74AHCT125 3-state buffer gate chip. It contains four buffer gates, each with an independent active low Output Enable (OE) pin to control the 3-state capability. (Note: You may substitute a 74HCT125 chip if you want.) \end_layout \begin_layout Standard To use the 74AHCT125, connect the chip's power pin (labeled V \begin_inset script subscript \begin_layout Plain Layout DD \end_layout \end_inset or V \begin_inset script subscript \begin_layout Plain Layout CC \end_layout \end_inset ) to 5 V and GND pin to ground. Then connect as follows: \end_layout \begin_layout Standard To level shift the radio's MISO (GPO1) pin, connect it to the input of a buffer gate on the 74AHCT125. Then connect the gate's output to the Arduino's MISO input. Finally, connect the buffer gate's Output Enable pin directly to the Arduino's Slave Select (SS) pin. (Arduino pin 10 by default. See \begin_inset CommandInset ref LatexCommand formatted reference "subsec:Configuring-SPI" \end_inset \begin_inset Quotes eld \end_inset \begin_inset CommandInset ref LatexCommand nameref reference "subsec:Configuring-SPI" \end_inset \begin_inset Quotes erd \end_inset to change this.) \end_layout \begin_layout Standard To level shift the radio's interrupt (GPO2) pin, connect it to the input of a buffer gate on the 74AHCT125. Then connect the gate's output to the Arduino's interrupt input. (Usually Arduino pin 2. See \begin_inset CommandInset ref LatexCommand formatted reference "subsec:Configuring-interrupts" \end_inset \begin_inset Quotes eld \end_inset \begin_inset CommandInset ref LatexCommand nameref reference "subsec:Configuring-interrupts" \end_inset \begin_inset Quotes erd \end_inset for more information.) Finally, connect the buffer gate's Output Enable pin to ground to keep the output \begin_inset Quotes eld \end_inset on \begin_inset Quotes erd \end_inset at all times. \end_layout \begin_layout Standard Because chips in the AHCT family are a recent design, they are robust and can operate at very high speeds. (About 100 MHz for the 74AHCT125.) As a result, I recommend using a 74AHCT125 chip when unidirectional level shifting from 3.3 to 5 volts. \end_layout \end_deeper \begin_layout Itemize A robust low to high voltage level shifter is a gate with an open drain output such as the 74HC266 exclusive-nor gate. To use this chip for level shifting, do the following: The gate chip's power pin (labeled V \begin_inset script subscript \begin_layout Plain Layout DD \end_layout \end_inset or V \begin_inset script subscript \begin_layout Plain Layout CC \end_layout \end_inset ) is connected to 3.3 V and the GND pin is connected to ground. One of the gate's inputs is connected to 3.3 V and the other input is connected to an Si4735 output that requires level shifting. Then the gate's output is connected to the Arduino's input. Finally, each gate output used requires a separate 4.7 k \begin_inset Formula $\Omega$ \end_inset pull-up resistor connected to 5 V. \end_layout \begin_deeper \begin_layout Standard The schematic in Figure \begin_inset CommandInset ref LatexCommand ref reference "fig:Open-drain-level-shift" \end_inset summarizes how to convert each signal. \end_layout \begin_layout Standard \begin_inset Float figure placement H wide false sideways false status open \begin_layout Plain Layout \noindent \align center \begin_inset Graphics filename Open drain.svg lyxscale 200 scale 175 \end_inset \begin_inset Caption Standard \begin_layout Plain Layout Open drain level shifter \begin_inset CommandInset label LatexCommand label name "fig:Open-drain-level-shift" \end_inset \end_layout \end_inset \end_layout \end_inset Because pull-up resistors are slow to bring the signal high, this level shifter only operates at slower speeds. I conservatively estimate it can handle 1 MHz or less. \end_layout \end_deeper \begin_layout Itemize The MC14504B or CD4504B chip is a robust, low to high level shifter. No pull-up resistor is required. Because this chip is a very old design, this level shifter only operates at slower speeds. I conservatively estimate it can handle 1 MHz or less. \end_layout \begin_layout Itemize The CD40109B chip is a robust, low to high level shifter that is very similar to the MC14504B, however, the CD40109B is slower. \end_layout \begin_layout Subsection Bidirectional level shifting between 3.3 and 5 volts \end_layout \begin_layout Standard This converts between a low voltage input or output on the radio and a high voltage input or output on the Arduino. The level shifting circuit automatically detects if the two sides change direction. All of these options can be used with either SPI, I2C, or any other I\SpecialChar breakableslash O signal, unless otherwise specified. \end_layout \begin_layout Standard Please note that some of these options have 3-state outputs controlled by an active \emph on high \emph default Output Enable pin. However, SPI's MISO signal requires a 3-state output controlled by an active \emph on low \emph default Output Enable pin connected to Slave Select (SS). Because none of these options support this, they cannot easily be used to level shift SPI's MISO signal, if the Arduino and radio are sharing the SPI bus with other devices. \end_layout \begin_layout Itemize The TXB0108 chip is designed as a robust general purpose level shifter. Adafruit sells a \begin_inset CommandInset href LatexCommand href name "breakout board" target "http://www.adafruit.com/products/395" \end_inset \begin_inset Foot status open \begin_layout Plain Layout http://www.adafruit.com/products/395 \end_layout \end_inset with this chip. Because this chip is a recent design, it can operate at very high speeds (20 MHz). Note that this chip will not work if either side has a pull-up resistor less than 50 k \begin_inset Formula $\Omega$ \end_inset . Because I2C requires a stronger pull-up resistor, typically 10 k \begin_inset Formula $\Omega$ \end_inset , and because I2C requires a level shifter with open drain outputs (which this chip does not do), this level shifter cannot be used with I2C. \end_layout \begin_layout Itemize The TXS0102 chip is designed as a robust I2C level shifter. Unfortunately, no one is currently selling a breakout board with this chip. \end_layout \begin_layout Itemize It is possible to build a bidirectional level shifter with a transistor and two pull-up resistors. A version of this circuit is available from SparkFun as part \begin_inset CommandInset href LatexCommand href name "BOB-8745" target "http://www.sparkfun.com/products/8745" \end_inset \begin_inset Foot status open \begin_layout Plain Layout http://www.sparkfun.com/products/8745 \end_layout \end_inset and from \begin_inset CommandInset href LatexCommand href name "Adafruit" target "http://www.adafruit.com/products/757" \end_inset \begin_inset Foot status open \begin_layout Plain Layout http://www.adafruit.com/products/757 \end_layout \end_inset . I personally used this method while developing my software. This shifter is specifically intended for use with I2C and has open drain (open collector) outputs. (It does not have 3-state outputs.) It should be fine for SPI provided you keep the clock speed at around 400 kHz, the same speed I2C normally uses. \end_layout \begin_layout Itemize The PCA9306 chip is designed as a robust I2C level shifter. SparkFun sells breakout board \begin_inset CommandInset href LatexCommand href name "BOB-10403" target "http://www.sparkfun.com/products/10403" \end_inset \begin_inset Foot status open \begin_layout Plain Layout http://www.sparkfun.com/products/10403 \end_layout \end_inset with this chip. Caution: Check comments for BOB-10403 on the SparkFun web site. Some people had problems with this board. \end_layout \begin_layout Subsection A terrible level shifter \end_layout \begin_layout Standard In Internet posts, some people have suggested using a diode in series to level shift from 3.3 V to 5 V. I checked this idea with my brother who is a professional electrical engineer who designs digital ICs for a living. He said this \emph on might \emph default work \series bold sometimes \series default for the SPI data pin (MISO) but will \series bold never \series default work for the interrupt pin. He said the technique will only work if the signal changes state between high and low very rapidly. Depending on the data sent over the SPI bus, this may or may not happen. However, because the interrupt line remains static most of the time, the diode cannot raise the voltage of the radio's interrupt signal. \end_layout \begin_layout Section Reliability of level shifted signals \end_layout \begin_layout Standard When using the Si4735 shield with a 5 V Arduino, it is important that reliable level shifting is used on the MISO SPI pin. When an interrupt is received, the library sends a GET_INT_STATUS command and then reads the status byte it returns. If the MISO signal is unreliable, the interrupt code received by the Arduino could be corrupted. This could cause the library to falsely believe that an interrupt it was waiting for has not yet arrived. \end_layout \begin_layout Standard This problem will be most noticeable, if the STC (Seek\SpecialChar breakableslash Tune Complete) interrupt is missed after changing the radio's frequency. In this case, the library will wait forever for the STC interrupt, despite the fact the radio has sent it. At this point, the only solution is manually pressing the Arduino's reset button. \end_layout \begin_layout Standard Another common symptom of an unreliable MISO connection is \family sans getFrequency() \family default or \family sans checkFrequency() \family default returning a bad frequency. \end_layout \begin_layout Standard To help prevent this problem, I make the following recommendations: \end_layout \begin_layout Itemize If possible, use a 3.3 V Arduino so no level shifting is required. \end_layout \begin_layout Itemize If you must use a 5 V Arduino, use a robust level shifter. \end_layout \begin_layout Itemize Keep the SPI bus frequency low. The library's default frequency is very slow. \end_layout \begin_layout Itemize Do not use a bread board with the level shifter. All those metal strips inside the bread board pickup stray RF noise and also slow down signals with stray capacitance. \end_layout \begin_layout Itemize Keep any connecting wires as short as possible. \end_layout \begin_layout Itemize Keep the radio's hardware away from your computer's fan and ventilation holes and any other sources of RF noise. While testing the library, I once placed the radio on top of a ventilation hole in my computer's case. The RF noise pouring out of this hole caused my radio to completely malfunction. Once I moved the radio a few inches away, the radio began to work. \end_layout \begin_layout Itemize Solder the connections, if possible. If you are having problems with a signal and it's not soldered, try disconnecti ng and then reconnecting its wires or try replacing its wires. \end_layout \begin_layout Itemize Wrap the final hardware design in sheet metal to protect it from stray RF noise. However, make sure that any antennas are outside this shielding or you will not receive any stations. \end_layout \begin_layout Section Choosing which \family sans Si4735 \family default class to use \end_layout \begin_layout Standard To represent human readable text, RDS mostly uses a custom 8-bit character set created by the European Broadcasting Union (EBU). To make this received text easier to use, the library can optionally translate the received EBU characters into either ASCII, Unicode, or the custom character sets found in popular text mode display controllers. Translation is controlled by choosing the correct class from those shown in table \begin_inset CommandInset ref LatexCommand ref reference "tab:Si4735-classes" \end_inset : \end_layout \begin_layout Standard \begin_inset Float table placement H wide false sideways false status open \begin_layout Plain Layout \noindent \align center \begin_inset Tabular <lyxtabular version="3" rows="5" columns="2"> <features tabularvalignment="middle"> <column alignment="left" valignment="top"> <column alignment="left" valignment="top"> <row> <cell alignment="left" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout Class \end_layout \end_inset </cell> <cell alignment="left" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout Returned characters \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \family sans Si4735 \end_layout \end_inset </cell> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout EBU (No translation) \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \family sans Si4735_ASCII \end_layout \end_inset </cell> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout ASCII \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \family sans Si4735_HD44780_A00 \end_layout \end_inset </cell> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout HD44780 display controller, ROM character set A00 \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \family sans Si4735_HD44780_A02 \end_layout \end_inset </cell> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout HD44780 display controller, ROM character set A02 \end_layout \end_inset </cell> </row> </lyxtabular> \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout \family sans Si4735 \family default classes \begin_inset CommandInset label LatexCommand label name "tab:Si4735-classes" \end_inset \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Standard \family sans Si4735 \family default is the base class and does no translating. To translate EBU characters into Unicode characters, use the \family sans Si4735 \family default class. You must then manually translate each EBU character received by calling either \family sans EBUToUCS2() \family default or \family sans EBUToUTF8() \family default . Every EBU character has an exact Unicode equivalent. \end_layout \begin_layout Description Note: The original \family sans Si4735 \family default base class always did a primitive ASCII translation. Old applications may want to change to the \family sans Si4735_ASCII \family default class. \end_layout \begin_layout Standard The \family sans Si4735_ASCII \family default derived class translates all received characters into ASCII characters. This translation should work with almost any text output device, but, its translations have the worst quality. \end_layout \begin_layout Standard The \family sans Si4735_HD44780_A00 \family default and \family sans Si4735_HD44780_A02 \family default derived classes work with both the HD44780 and ST7066 controller chips, commonly found in text mode displays. This includes LCDs, OLEDs, VFDs, etc. They will not work with graphic mode displays designed to show pictures and other fancy graphics. \end_layout \begin_layout Standard The \family sans Si4735_HD44780_A00 \family default derived class translates all received characters into the custom character set used by most display controllers. The HD44780 controller should have ROM character set A00 and the ST7066 controller should have ROM character set 0A. All text displays (LCD, etc.) available to hobbyists will use this character set and will therefore work with this class. \end_layout \begin_layout Standard The \family sans Si4735_HD44780_A02 \family default derived class translates all received characters into a custom character set rarely used by display controllers. The HD44780 controller should have ROM character set A02. This character set gives better translations for less commonly used EBU characters, but displays using this controller are impossible for hobbyists to find. \end_layout \begin_layout Standard If you do not know which class to use for your text mode display controller, try \family sans Si4735_HD44780_A00 \family default . \end_layout \begin_layout Standard When the derived classes translate EBU characters, they sometimes do not have an exact match in the target character set. In this case, characters are either transliterated or, as recommended by the RDS standard, a space is substituted. \end_layout \begin_layout Description Note: Throughout this library's documentation and source code, any reference to the \family sans Si4735 \family default base class applies to all derived classes unless otherwise indicated. \end_layout \begin_layout Section \begin_inset CommandInset label LatexCommand label name "sec:Initializing-the-radio" \end_inset Initializing the radio and library and setting the receive band \end_layout \begin_layout Standard You must call \family sans begin() \family default to initialize this library before calling any other methods. When called, it initializes the SPI or I2C bus. Because you may wish to do this yourself or with another library, you may tell \family sans begin() \family default to skip initializing these buses by calling \family sans begin(BEGIN_DO_NOT_INIT_BUS) \family default . \end_layout \begin_layout Standard The second argument to \family sans begin() \family default is the bus argument. For SPI, it gives the clock divider to pass to \family sans SPIClass :: setClockDivider() \family default . If no bus argument is given to \family sans begin() \family default , \family sans RADIO_SPI_CLOCK_DIV \family default in \family sans Si4735.h \family default is used. \end_layout \begin_layout Standard Example code to set the SPI bus clock to divide by 8. On a 16 MHz Arduino, this will set the SPI clock to \begin_inset Formula $16\textrm{ MHz}\div8=2\textrm{ MHz}$ \end_inset : \end_layout \begin_layout LyX-Code begin(BEGIN_DEFAULT, SPI_CLOCK_DIV8); \end_layout \begin_layout Standard For I2C, the bus argument gives the address of the radio. The radio will respond to one of two I2C addresses. The address used by the radio is selected by the signal given to the radio's SEN\SpecialChar breakableslash SS pin. The following table gives the possible addresses: \end_layout \begin_layout Quote \begin_inset Tabular <lyxtabular version="3" rows="3" columns="2"> <features tabularvalignment="middle"> <column alignment="left" valignment="top"> <column alignment="center" valignment="top"> <row> <cell alignment="left" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout I2C bus argument for \family sans begin() \end_layout \end_inset </cell> <cell alignment="center" valignment="top" bottomline="true" usebox="none"> \begin_inset Text \begin_layout Plain Layout SEN pin \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \family sans RADIO_I2C_ADDRESS_HIGH \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout HIGH \end_layout \end_inset </cell> </row> <row> <cell alignment="left" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout \family sans RADIO_I2C_ADDRESS_LOW \end_layout \end_inset </cell> <cell alignment="center" valignment="top" usebox="none"> \begin_inset Text \begin_layout Plain Layout LOW \end_layout \end_inset </cell> </row> </lyxtabular> \end_inset \end_layout \begin_layout Standard If no bus argument is given, \family sans RADIO_I2C_ADDRESS \family default in \family sans Si4735.h \family default is used. By default, \family sans RADIO_I2C_ADDRESS \family default equals \family sans RADIO_I2C_ADDRESS_HIGH \family default . Note that the Si4707 breakout board has a 10 k \begin_inset Formula $\Omega$ \end_inset pull-up resistor connected to SEN to make it go high. \end_layout \begin_layout Standard Example code to set the I2C address to its low value: \end_layout \begin_layout LyX-Code begin(BEGIN_DEFAULT, RADIO_I2C_ADDRESS_LOW); \end_layout \begin_layout Standard The radio has a low power \begin_inset Quotes eld \end_inset off \begin_inset Quotes erd \end_inset mode and modes for each receive band. After calling \family sans begin() \family default , the radio is in the low power \family sans RADIO_OFF \family default mode. You change the radio's mode by calling \family sans setMode() \family default . For example, calling \family sans setMode(FM) \family default powers up the radio and sets the receive mode to the FM band. See \family sans Si4735.h \family default for a list of all supported modes. \end_layout \begin_layout Standard The radio's current mode is returned by \family sans getMode() \family default . \end_layout \begin_layout Standard By calling \family sans setMode(RADIO_OFF) \family default , the radio goes back into low power mode. To kill all power to the radio, call \family sans end() \family default . To restore power later, call \family sans begin() \family default . \end_layout \begin_layout Standard \begin_inset Box Shadowbox position "t" hor_pos "c" has_inner_box 1 inner_pos "t" use_parbox 0 use_makebox 0 width "100col%" special "none" height "1in" height_special "totalheight" thickness "0.4pt" separation "3pt" shadowsize "4pt" framecolor "black" backgroundcolor "none" status open \begin_layout Description \series bold Warning: Unlike previous versions of this library from other people, \family sans begin() \family default does \bar under not \bar default set the receive band. Call \family sans setMode() \family default to do this. \series default As a result, the following code fragment: \end_layout \begin_deeper \begin_layout LyX-Code radio.begin(FM); \end_layout \begin_layout Plain Layout should be changed to: \end_layout \begin_layout LyX-Code radio.begin(); \end_layout \begin_layout LyX-Code radio.setMode(FM); \end_layout \begin_layout Plain Layout Open the \family sans Changes.text \family default file in a programmer's text editor to see why this change was made. \end_layout \end_deeper \end_inset \end_layout \begin_layout Standard \family sans setMode() \family default sets up the given band's top and bottom frequency and its spacing based on the previously set locale. (See \begin_inset CommandInset ref LatexCommand formatted reference "sec:Localization" \end_inset \begin_inset Quotes eld \end_inset \begin_inset CommandInset ref LatexCommand nameref reference "sec:Localization" \end_inset . \begin_inset Quotes erd \end_inset ) You may override these band settings by calling \family sans setBandTop() \family default , \family sans setBandBottom() \family default , and \family sans setSpacing() \family default after calling \family sans setMode() \family default . To get the current band settings, call \family sans getBandTop() \family default , \family sans getBandBottom() \family default , and \family sans getSpacing() \family default . \end_layout \begin_layout Standard There are a small number of differences between the Si4735-C40 and Si4735-D60. As a result, \family sans setMode() \family default sends the GET_REV command to the radio and saves the results in the \family sans revision \family default structure, located in the public part of the \family sans Si4735 \family default class structure. This permits your software and this library to determine which chip is being used and adapt themselves to it. For a list of differences and compatibly concerns, see Appendix A and B in the \begin_inset Quotes eld \end_inset Si47xx Programming Guide. \begin_inset Quotes erd \end_inset (Please note that the audio noise bug in FM receive mode documented in Appendix B is corrected by this library.) \end_layout \begin_layout Section Using the library with or without interrupts \end_layout \begin_layout Standard Previous versions of this library from other people did not support receiving interrupt signals from the radio chip. Instead, the library and application would poll the radio to see if some event had occurred yet. This approach causes a large amount of bus traffic between the Arduino and radio chips. This is undesirable because bus traffic can introduce noise into the radio chip which can be heard in the audio output. Also, the manuals say that bus traffic can harm tuning operations when using an external crystal connected to the RCLK and GPO3 pins with the radio chip's internal oscillator circuit. (Please note that the Si4735 shield uses this setup, and therefore, shield users should avoid any bus traffic while tuning a new station.) \end_layout \begin_layout Standard This library supports waiting for an interrupt signal from the radio chip before asking it what event has taken place. Or, you can choose to poll the radio at any time. \end_layout \begin_layout Standard The library automatically tells the radio to send STC (Seek\SpecialChar breakableslash Tune Complete), RDS (Radio Data System), and RSQ (Received Signal Quality) interrupts. \end_layout \begin_layout Standard To keep the design simple, the library does not use a complex interrupt handler. Instead we just poll the AVR's interrupt registers to see when an interrupt pulse has been received from the radio chip. On ARM based Arduinos, a short interrupt handler sets a flag variable and then returns. Later, the library polls this flag variable to check for interrupts. \end_layout \begin_layout Subsection Tuning \end_layout \begin_layout Standard To change to a particular frequency, call \family sans tuneFrequency() \family default . To increment or decrement the current frequency, call \family sans frequencyUp() \family default or \family sans frequencyDown() \family default . \end_layout \begin_layout Standard To seek to the next or previous frequency, call \family sans seekUp() \family default or \family sans seekDown() \family default . To cancel a seek operation call \family sans cancelSeek() \family default . \end_layout \begin_layout Standard To manually ask the radio if a seek or tune operation has completed, call \family sans getFrequency() \family default . It immediately asks the radio if tuning is complete and, if so, its current frequency. \family sans checkFrequency() \family default works the same but only asks the radio if the STC interrupt has been received. \end_layout \begin_layout Standard \family sans currentFrequency() \family default returns the radio's current frequency or \family sans 0 \family default if unknown. (The frequency is usually unknown because a seek operation is underway.) Note: \family sans currentFrequency() \family default does not indicate if the previous tune or seek operation has completed. It only returns the frequency from the last tune operation or call to \family sans getFrequency() \family default or \family sans checkFrequency() \family default . \end_layout \begin_layout Standard Calling \family sans waitSTC() \family default will not return until the STC interrupt has been received. This is useful after calling \family sans tuneFrequency() \family default , \family sans frequencyUp() \family default , \family sans frequencyDown() \family default , \family sans seekUp() \family default , or \family sans seekDown() \family default . \end_layout \begin_layout Standard Methods \family sans tuneFrequencyAndWait() \family default , \family sans frequencyUpAndWait() \family default , and \family sans frequencyDownAndWait() \family default automatically call \family sans waitSTC() \family default after changing the frequency. \end_layout \begin_layout Description Note: Seeking on some bands (like SW) can take a long time to find a station. Therefore, it is recommended that the application using this library handle seeks in the following way. First, call \family sans seekUp() \family default or \family sans seekDown() \family default . Second, enter a loop which looks for two events: either the user wants to cancel the seek or the STC interrupt has been received because the seek has finished. The following incomplete code fragment shows how to do this: \end_layout \begin_deeper \begin_layout LyX-Code radio.seekUp(); \end_layout \begin_layout LyX-Code word station; \end_layout \begin_layout LyX-Code bool user_cancel_seek=false; \end_layout \begin_layout LyX-Code do{ \end_layout \begin_layout LyX-Code //add code here to see if user wants to cancel seek \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code if(user_cancel_seek == true){ \end_layout \begin_layout LyX-Code station = radio.cancelSeek(); \end_layout \begin_layout LyX-Code break; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code //check if seek finished, that is, STC interrupt received \end_layout \begin_layout LyX-Code station = radio.checkFrequency(); \end_layout \begin_layout LyX-Code }while(station == 0); \end_layout \end_deeper \begin_layout Subsection RDS \end_layout \begin_layout Standard There are two methods for reading RDS data, \family sans getRDS() \family default and \family sans checkRDS() \family default . \family sans getRDS() \family default immediately asks the radio to send any RDS data by sending an FM_RDS_STATUS command. \family sans checkRDS() \family default first checks if an RDS interrupt has been received. If so, \family sans checkRDS() \family default calls \family sans getRDS() \family default . Otherwise \family sans checkRDS() \family default returns immediately. RDS data is stored inside the \family sans rds \family default structure, located in the public part of the \family sans Si4735 \family default class structure. \end_layout \begin_layout Standard \family sans getCallSign() \family default translates an RBDS (USA) PI code into the station's call letters. Note, this works for US stations because their PI codes are based on their call letters. In other countries, PI codes are arbitrarily assigned. We would need to create a large database matching PI codes to station IDs. \end_layout \begin_layout Standard \family sans getProgramTypeStr() \family default translates the ProgramType code into an English message. Works for both RDS and RBDS. \end_layout \begin_layout Standard \family sans getLocalTime() \family default and \family sans getLocalDateTime() \family default return the local time returned by the station. \end_layout \begin_layout Subsection RSQ \end_layout \begin_layout Standard There are two methods for reading RSQ information, \family sans getRSQ() \family default and \family sans checkRSQ() \family default . \family sans getRSQ() \family default immediately asks the radio for the current RSQ information by sending an RSQ_STATUS command. \family sans checkRSQ() \family default first checks if an RSQ interrupt has been received. If so, \family sans checkRSQ() \family default calls \family sans getRSQ() \family default . Otherwise \family sans checkRSQ() \family default returns immediately. \end_layout \begin_layout Standard The RSQ interrupt is sent by the radio when certain thresholds have occurred. These thresholds are configured by setting properties with the \family sans setProperty() \family default method. For FM, these properties include: \end_layout \begin_layout LyX-Code PROP_FM_RSQ_INT_SOURCE \end_layout \begin_layout LyX-Code PROP_FM_RSQ_SNR_HI_THRESHOLD \end_layout \begin_layout LyX-Code PROP_FM_RSQ_SNR_LO_THRESHOLD \end_layout \begin_layout LyX-Code PROP_FM_RSQ_RSSI_HI_THRESHOLD \end_layout \begin_layout LyX-Code PROP_FM_RSQ_RSSI_LO_THRESHOLD \end_layout \begin_layout LyX-Code PROP_FM_RSQ_MULTIPATH_HI_THRESHOLD (Not on Si4735-C40) \end_layout \begin_layout LyX-Code PROP_FM_RSQ_MULTIPATH_LO_THRESHOLD (Not on Si4735-C40) \end_layout \begin_layout LyX-Code PROP_FM_RSQ_BLEND_THRESHOLD \end_layout \begin_layout Standard AM has similar properties. Not all properties are supported by all chips. See the “Si47xx Programming Guide \begin_inset Quotes erd \end_inset for more information on these properties. \end_layout \begin_layout Subsection Manually reading interrupts \end_layout \begin_layout Standard You may manually ask the radio what interrupts have been sent by calling \family sans getInterrupts() \family default . This sends a GET_INT_STATUS command to the radio, saves the result internally, and then returns the result. \end_layout \begin_layout Standard Also, you may call \family sans currentInterrupts() \family default to ask the library what interrupts have been received. If a new interrupt signal has been received by the Arduino, \family sans currentInterrupts() \family default calls \family sans getInterrupts() \family default . If no new interrupt signal has been received, \family sans currentInterrupts() \family default returns the previously saved interrupt status. \end_layout \begin_layout Section \begin_inset CommandInset label LatexCommand label name "sec:Localization" \end_inset Localization \end_layout \begin_layout Standard Localization is done in two parts: an ITU region and a locale within that region. Both are set by calling \family sans setRegionAndLocale() \family default . \end_layout \begin_layout Standard The ITU (International Telecommunication Union) has divided the world into 3 regions. For the most part, radio broadcasting is the same throughout each region. In some cases, the library subdivides regions into subregions. To handle exceptions within each region or subregion, you may also set a locale. \end_layout \begin_layout Standard For example, the USA is in region 2, subregion North America. However, unlike other countries, it uses RBDS instead of RDS. Therefore, the USA has a separate locale. To setup the library for the USA: \end_layout \begin_layout LyX-Code radio.setRegionAndLocale(REGION_2_NA, LOCALE_US); \end_layout \begin_layout Standard Please note that the library defaults to the USA. \end_layout \begin_layout Standard For locations that do not need localization beyond specifying their region and subregion, a special locale code is used: \family sans LOCALE_OTHER \family default . For example, most of Europe should work by calling: \end_layout \begin_layout LyX-Code radio.setRegionAndLocale(REGION_1, LOCALE_OTHER); \end_layout \begin_layout Standard \family sans setRegionAndLocale() \family default should only be called while the radio is in the low power \family sans RADIO_OFF \family default mode. \end_layout \begin_layout Standard \family sans getRegion() \family default returns the current region and subregion code. \family sans getLocale() \family default returns the current locale code for the current region and subregion. \end_layout \begin_layout Standard See the \family sans Si4735.h \family default file for the list of region and locale constants and more information on their use. \end_layout \begin_layout Section Volume \end_layout \begin_layout Standard The volume can be changed by calling \family sans volumeUp() \family default or \family sans volumeDown() \family default . Both methods take an argument giving the amount to increase or decrease the volume. Also, you can set the volume to a given value by calling \family sans setVolume() \family default . All three methods return the new volume setting. To read the current volume setting at any time, call \family sans getVolume() \family default . \end_layout \begin_layout Standard \family sans mute() \family default and \family sans unmute() \family default activate or deactivate muting. You can also toggle mute by calling \family sans toggleMute() \family default . It then returns the new mute status. \family sans getMute() \family default returns true if mute is currently active. \end_layout \begin_layout Standard The volume and mute methods can be called while the radio is powered up in a receive mode or the radio is in the low power \family sans RADIO_OFF \family default mode. \end_layout \begin_layout Section Sending commands to the radio \end_layout \begin_layout Standard \noindent The most useful commands already have library methods. However, you may choose to manually send commands to the radio by calling \family sans sendCommand() \family default or \family sans sendCommand_P() \family default . To get the results, call \family sans getStatus() \family default for the single byte status code or \family sans getResponse() \family default for the longer 16 byte response. For your convenience, predefined command codes can be found in \family sans Si4735.h \family default . \end_layout \begin_layout Standard Many features are controlled with properties. Call \family sans setProperty() \family default to set a property and \family sans getProperty() \family default to read its current value. For your convenience, predefined property codes can be found in \family sans Si4735.h \family default . \end_layout \end_body \end_document