Summary:

Transmit AM Radio using only a microcontroller. Based on Scott Harden's Ridiculously Simple AVR AM Radio Transmitter.

Materials:

materials-3

  1. ATtiny85 AVR Microcontroller
  2. Breadboard & Breadboard cables, (OR)
  3. ATtiny Dev Board
  4. ISP Programmer
  5. ISP 6-Pin Cable
  6. SDR and receiver, or AM Radio (for testing)
  7. avr-gcc and avrdude

Process:

AM Theory:

Amplitude Modulation works by varying the intensity of a continuous sinusoidal waveform. To create a signal we need a carrier waveform, and a signal to send. Finally we'll need a way to modulate the carrier using the signal.

am

Since the ATtiny85 has an internal oscillating clock, we can use that as a carrier signal for AM modulation. Then, we have to create a signal to send. This will be based on International Morse code. Then, using an external transistor we'll modulate the AM signal on or off by pulling the transistor low or high.

H    E L    L    O       W   O   R   L    D   . 
.... . .-.. .-.. ---     .-- --- .-. .-.. -.. ·-·-·-

Connections:

After struggling through a number of ATtiny projects laboriously connecting every pin of the ISP programmer to a breadboarded microcontroller I finally decided to buy a dev board. The board breaks out the pins in the ISP 6 format (plus two more GPIO) for easy connection with a programmer. For fast dev I'm going to be using this. Just plug the ATtiny into the dev board, bend the GPIO pins out of the way, and attach the ISP-6 cable to the ISP programmer.

connect

If you don't have a dev board you need to connect the ISP-6 Pins to the correct ATtiny pins using breadboard jumpers, following the below schematic.

isp6

Also make sure to plug in the SDR or AM radio.

Code:

We'll only need some basic AVR libraries, for I/O and timing.

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

To generate our signal we make a function called beep. It creates a

void beep(){
    // 50 cycles of 2 ms = 100 ms of 500 Hz
	for(char i=50;i;i--){
        // Toggle the pin on / off
        PORTB|=_BV(PB0);_delay_ms(1);
        PORTB&=~_BV(PB0);_delay_ms(1);
	}
}

Then all we need to do is create some macros to make writing Morse code easier.

void rest(){_delay_ms(100);}

// Defined by Morse standards
void dot(){beep();rest();}
void dash(){beep();beep();beep();rest();}
void space(){rest();rest();}
void space2(){space();space();}

Finally, we add a main function that enables output on PB0 (Pin 5), and spells out some code.

int main(){
    // Set PB0 pin to output
    DDRB|=_BV(PB0);
    
	for(;;){ // ever
		dot(); dot(); dot(); dot(); space();			// H
		dot(); space();									// E
		dot(); dash(); dot(); dot(); space();			// L
		dot(); dash(); dot(); dot(); space();			// L
		dash(); dash(); dash(); space();				// O
        dash2();
		dot(); dash(); dash(); space();					// W
		dash(); dash(); dash(); space();				// O
		dot(); dash(); dot(); space();					// R
		dot(); dash(); dot(); dot(); space();			// L
		dash(); dot(); dot(); space();					// D
		dot(); dash(); dot(); dash(); dot(); dash(); 	// .
		_delay_ms(1000); // silence
	}
	return 0;
}

Compilation and Flashing:

With AVR-GCC and avrdude, programming the ATtiny is super easy. Sample Makefiles can be found online. The important parameters are outlined below. To calculate the fuses we need, use an AVR fuse calculator.

# Makefile

# What hardware we're using
DEVICE     = attiny85

# Clock is 8 MHz, so the carrier will be 8 MHz
CLOCK      = 8000000UL

# We're using an ISP programmer, which is called usbtiny by avrdude
PROGRAMMER = -c usbtiny

# The lFuse enables clock output on Pin 3, and keeps the clock at 8 MHz
FUSES      = -U lfuse:w:0xa2:m -U hfuse:w:0xdf:m -U efuse:w:0xff:m 

Testing:

Apply 5V to the ATtiny 5V pin, GND to GND, and add a length of wire to the PB0 (MOSI) pin to act as a makeshift antenna. Then tune a radio to around 8000 kHz (8 MHz), or an even multiple of that frequency.[1] Because of the limitations of my SDR I had to pick a multiple above 24 MHz.

test-1

We can see little pulses of AM signal being generated, spelling out a message in Morse.

Future Work:

This would need significant hardware work to be a clean and legal transmitter.

It also serves as an excellent introduction to advanced clock manipulation on the ATtiny.


  1. Since our clock generates square wave pulses, we'll hear pronounced harmonics at every multiple of the fundamental frequency, diminishing in strength as they increase. ↩︎