Created
July 7, 2019 23:35
-
-
Save 9nut/8a4a5751fee063cce528021c87eac489 to your computer and use it in GitHub Desktop.
Arduino sketch for controlling NS73M FM transmitter with an ATtiny85
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
12-1-2007 | |
Cai Maver, caimaver(at)yahoo.com | |
ARRRduino+NS73M v0.3 | |
This code allows an Arduino Diecimila to control an NS73M FM Transmitter Module (Arrr matey!) | |
This sets the NS73M (available from Sparkfun, SKU#: WRL-08482) to transmit | |
at 2mW with 75us pre-emphasis (the standard for North America) on 97.3 MHz. | |
Use this formula to determine the register values for a new transmitting frequency (f): | |
(f + 0.304)/0.008192 <-- use only the whole number and convert the result to | |
16-bit binary where the lower byte goes in register 3 | |
and the upper byte goes in register 4 | |
ex.: for 97.3 MHz, (97.3 + 0.304)/0.008192 = 11914.55... | |
11914 = B0010111010001010 so Reg 3=B10001010 and Reg 4=B00101110 | |
A future version of this code will allow for on-the-fly frequency changes | |
Thanks to Nathan Seidle at Sparkfun and Jim "ZAPNSPARK" G. for sharing their NS73M code! | |
Revised 2012-02-28: | |
using tone() to output audio on Pin 9, to NS73M Left In (LIN) through 100 ohm R. | |
details about wiring, etc, on our wiki page: | |
http://wiki.dxarts.washington.edu/groups/general/wiki/5c103/Using_NS73M_FM_Transmitter.html | |
rtwomey@u.washington.edu | |
Revised 2019: | |
mods to make it easier to play notes and adjust for attiny85 pins. | |
skipt | |
*/ | |
#include "pitches.h" | |
#if defined(__AVR_ATtiny85__) | |
#define LATCHPIN 0 | |
#define DATAPIN 1 | |
#define CLOCKPIN 2 | |
#define AUDIOPIN 4 | |
#undef DEBUG | |
#elif defined(__AVR_ATmega328p__) | |
#define LATCHPIN 10 | |
#define DATAPIN 11 | |
#define CLOCKPIN 12 | |
#define AUDIOPIN 9 | |
#define DEBUG | |
#else | |
#error No configuration for board type | |
#endif | |
int CK = CLOCKPIN; | |
int DA = DATAPIN; | |
int LA = LATCHPIN; | |
int AudioPin = AUDIOPIN; // left audio-in pin | |
struct noteDurations { | |
int note; | |
int dur; | |
int del; | |
}; | |
// Close Encounters of the Third Kind. | |
struct noteDurations notes[] = { | |
{NOTE_G5, 1500, 500}, | |
{NOTE_A5, 1500, 500}, | |
{NOTE_F5, 1500, 500}, | |
{NOTE_F4, 1500, 500}, | |
{NOTE_C5, 1500, 2000} | |
}; | |
int numNotes = (sizeof(notes)/sizeof(notes[0])); | |
int nextNote = 0; | |
void setup(){ | |
#if defined(DEBUG) | |
Serial.begin(9600); //begin Serial connection for debugging | |
#endif | |
// pinMode(AudioPin, OUTPUT); | |
pinMode(CK, OUTPUT); | |
pinMode(DA, OUTPUT); | |
pinMode(LA, OUTPUT); | |
digitalWrite(LA, LOW); //unlatch transmitter | |
delay(100); //Wait for VDD to settle | |
spi_send(0x0E, B00000101); //Software reset | |
spi_send(0x01, B10110100); //Register 1: forced subcarrier, pilot tone on | |
spi_send(0x02, B00000011); //Register 2: Unlock detect off, 2mW Tx Power | |
spi_send(0x03, B10001010); //Register 3: Set broadcast freq to 97.3, lower byte | |
spi_send(0x04, B00101110); //Register 4: Set broadcast freq to 97.3, upper byte | |
spi_send(0x08, B00011010); //Register 8: set Osc on band 2 | |
spi_send(0x00, B10100001); //Register 0: 200mV audio input, 75us pre-emphasis on, crystal off, power on | |
spi_send(0x0E, B00000101); //Software reset | |
spi_send(0x06, B00011110); //Register 6: charge pumps at 320uA and 80 uA | |
#if defined(DEBUG) | |
Serial.print("Transmitting"); //for debugging | |
#endif | |
} | |
void loop(){ | |
int curNote = nextNote; | |
tone(AudioPin, notes[curNote].note, notes[curNote].dur); | |
delay(notes[curNote].del); | |
nextNote++; | |
nextNote %= numNotes; | |
if (nextNote == 0) { | |
noTone(AudioPin); | |
} | |
delay(notes[curNote].del); | |
} | |
void spi_send(byte reg, byte data) //routine to send Register Address and Data as LSB-first SPI | |
{ | |
int x; | |
int n; | |
digitalWrite(LA, LOW); | |
for(x = 0 ; x < 4 ; x++) //send four-bit register address | |
{ | |
digitalWrite(CK, LOW); //Toggle the SPI clock | |
n = (reg >> x) & 1; //n is the xth bit of the register byte | |
if (n == 1){ | |
digitalWrite(DA, HIGH); //Put high bit on SPI data bus | |
} | |
else { | |
digitalWrite(DA, LOW); //Put low bit on SPI data bus | |
} | |
#if defined(DEBUG) | |
Serial.print(n); //send bit to serial connection for debugging | |
#endif | |
digitalWrite(CK, HIGH); //Toggle the SPI clock | |
} | |
for(x = 0 ; x < 8 ; x++) //send eight-bit register data | |
{ | |
digitalWrite(CK, LOW); //Toggle the SPI clock | |
n = (data >> x) & 1; | |
if (n == 1){ | |
digitalWrite(DA, HIGH); //Put high bit on SPI data bus | |
} | |
else { | |
digitalWrite(DA, LOW); //Put low bit on SPI data bus | |
} | |
#if defined(DEBUG) | |
Serial.print(n); //send bit to serial connection for debugging | |
#endif | |
digitalWrite(CK, HIGH); //Toggle the SPI clock | |
} | |
delayMicroseconds(1); //might not be needed, supposedly unstable command anyway | |
digitalWrite(LA, HIGH); //Latch this transfer | |
delayMicroseconds(4); | |
digitalWrite(LA, LOW); | |
digitalWrite(CK, LOW); //This is to keep CK pin at 0V at end of data transfer | |
#if defined(DEBUG) | |
Serial.print("\n"); // send new-line to serial for debugging | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment