Skip to content

Instantly share code, notes, and snippets.

@9nut
Created July 7, 2019 23:35
Show Gist options
  • Save 9nut/8a4a5751fee063cce528021c87eac489 to your computer and use it in GitHub Desktop.
Save 9nut/8a4a5751fee063cce528021c87eac489 to your computer and use it in GitHub Desktop.
Arduino sketch for controlling NS73M FM transmitter with an ATtiny85
/*
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