# DAC Hacks for Circuit Playground Express & other ATSAMD21 Boards

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/041/852/medium800/hacks_banner-pic.jpg?1495329585)

With each&nbsp; **new generation** &nbsp;of microcontrollers we tend&nbsp;to dwell on quantifiables like **memory** and **speed** — bigger, faster programs! At the same time, new devices often bring&nbsp;_additional capabilities_ that are overlooked at first glance. These features open whole new doors, _beyond_ what program size or speed can do.

The SAMD ARM M0 microcontroller used in Circuit Playground Express, Feather M0 and other Adafruit boards with the “Express” or “M0” designations — along with the Arduino Zero — include some intriguing new features, among them:

- **A _digital-to-analog converter_ (DAC).** Pin A0 can provide a **true analog voltage** between 0 and 3.3 Volts. Previously, Arduino’s so-called analogWrite() function wasn't _really_ analog — it generated a pulse-width-modulated _digital_ signal.
- **_Direct memory access_ (DMA)** allows data transfers between memory and peripherals (including the DAC) very quickly and without CPU intervention — it goes about its task in the background while other code continues to run at 100% speed.

We’ll demonstrate by generating **composite TV** and **AM radio** signals straight&nbsp;from the board. **No** shields or breadboards or soldering extra components, just some simple test leads!

While the projects shown here have a vintage&nbsp;rinky-dink flair, the fact that a microcontroller can do this _entirely on its own_ — no extra parts, just some wires — is pretty remarkable. Rather than just thinking bigger and faster, what unconventional ideas and applications might you hatch&nbsp;from new hardware?&nbsp;None of this is really what the DAC is intended for, but it’s cool in a demo-scene kind of way.

# Getting Started

These demo projects will&nbsp;require:

- An Atmel **SAMD M0** -based microcontroller board such as [Circuit Playground Express](https://www.adafruit.com/product/3333), [Feather M0](https://www.adafruit.com/product/2772) or [Arduino Zero](https://www.adafruit.com/product/2843). 8-bit AVR boards and&nbsp;“classic” 8-bit Circuit Playground are&nbsp;not compatible.
- Corresponding board support enabled in the Arduino IDE:&nbsp; **Tools→Board→Boards Manager…** Adafruit boards require an extra step first, [explained in this guide](../../../adafruit-feather-m0-basic-proto/setup).
- For Circuit Playground Express: some [alligator clip test leads](https://www.adafruit.com/product/1008). For other boards, some solid-core wire.

To confirm that SAMD board support is working, try uploading the basic “blink” sketch to a board. To confirm the Adafruit\_ZeroDMA library is correctly installed, check that the&nbsp;Files→Examples→Adafruit\_ZeroDMA rollover menu is present.

Each of the projects that follow&nbsp;will require its own additional library, again manually installed.

# DAC Hacks for Circuit Playground Express & other ATSAMD21 Boards

## Composite Video Output

![](https://cdn-learn.adafruit.com/assets/assets/000/041/851/medium800/hacks_vid-pic.jpg?1495329339)

The DAC is _just_ fast enough to generate low-resolution **composite video** that can be viewed on a television or monitor with composite video input (typically a yellow **RCA connector** ).

There are very few pixels, and it’s only grayscale, but it’s sufficient&nbsp;for creating simple games or to print&nbsp;readings from sensors.

To use this, download and manually install the **Adafruit\_CompositeVideo** library:

[Download Adafruit_CompositeVideo Library](https://github.com/adafruit/Adafruit_CompositeVideo/archive/master.zip)
This also requires the **Adafruit\_GFX** library, which is much easier to install using the Arduino Library Manager:&nbsp; **Sketch→Include Library→Manage Libraries…** (enter “ **GFX** ” in the search field).

Earlier versions (pre-1.8.10) also require installing **Adafruit\_BusIO** (newer versions will handle this one automatically).

After the Adafruit\_CompositeVideo library is installed, there are a couple of example sketches. One prints the current value from the Circuit Playground light sensor, another shows large horizontal-scrolling text.

Connect a couple of test leads to **pin A0** and any **ground** pin.

![hacks_gator-out.jpg](https://cdn-learn.adafruit.com/assets/assets/000/041/843/medium640/hacks_gator-out.jpg?1495261982)

At the other end, connect **A0** to the “ **tip** ” (center) of the composite video connector, and **ground** to the “ **ring** ” (outside).

Depending on the TV/monitor connection and available cabling, you may need a spare composite cable or male-to-male adapter to get something you can clip onto.

Since I’ll be testing the code often, I cobbled together a somewhat more permanent connector from a spare cable and test leads, but it’s not necessary to go to such lengths if just trying it out.

![hacks_composite-clip.jpg](https://cdn-learn.adafruit.com/assets/assets/000/041/844/medium640/hacks_composite-clip.jpg?1495262027)

![hacks_vid-cable.jpg](https://cdn-learn.adafruit.com/assets/assets/000/041/845/medium640/hacks_vid-cable.jpg?1495262190)

# How It Works
NTSC video runs at 29.97 frames per second. Each frame is comprised of 525 horizontal scanlines. Each scanline starts and ends with&nbsp;carefully-timed synchronization signals, with image data in-between: an analog voltage from about 0.3 to 1.0V determines the brightness at that point along the scanline.

Twice per frame, there are also vertical synchronization signals following a specific timing and pattern.

Some of these “blips” are just a couple of microseconds long!&nbsp;Digital outputs can easily manage such timing, but for the SAMD DAC this is challenging…the makeshift&nbsp;video signal is _just good enough_ for most screens&nbsp;to latch on to.

![hacks_scope-vsync.png](https://cdn-learn.adafruit.com/assets/assets/000/041/847/medium640/hacks_scope-vsync.png?1495322292)

![hacks_scope-scanline.png](https://cdn-learn.adafruit.com/assets/assets/000/041/887/medium640/hacks_scope-scanline.png?1495518602)

# Creating New TV Projects
To use the library, add these two lines at the top of your sketch:

```auto
#include &lt;Adafruit_GFX.h&gt;
#include &lt;Adafruit_CompositeVideo.h&gt;
```

Then, before the setup() function, declare a global object of type **Adafruit\_NTSC40x24** :

```auto
Adafruit_NTSC40x24 display;
```

(It’s called this just in case other resolutions are supported in the future…but don’t hold your breath, I’ve tried going higher and the DAC can’t quite make a stable image.)

Then, inside your setup() function, call the object’s begin() function to enable composite video out on the A0 pin:

```auto
display.begin();
```

Because it builds upon the Adafruit\_GFX library, [all the same drawing functions](../../../../adafruit-gfx-graphics-library) (including fonts) are available as with our other Arduino-compatible displays. “Colors”&nbsp;passed to the drawing functions should be **8-bit grayscale values** ( **0 to 255** , where 0=black, 255=white).

```auto
display.drawLine(0, 0, 39, 23, 128); // Gray line, corner-to-corner
display.setTextColor(255);           // White text
display.print("Hello World");
```

# Limitations

- **Circuit Playground Express speaker is disabled;** tone() and other audio code&nbsp; **will not work** in combination with this
- **40x24** pixel resolution; actual usable area **may be slightly smaller** due to overscan
- **Grayscale only**

Adafruit\_CompositeVideo and Adafruit\_AMRadio (on the next page) both use the DAC peripheral and the same timer/counter; the two libraries **can not be used&nbsp;at the same time**.

The video resolution is extremely crude…it’s more a novelty than anything else. If you need high-quality visuals from a small board, consider a Raspberry Pi Zero!

Folks have generated much sharper&nbsp;video (with color, even!) from much more modest hardware. These all require extra components though. The benefit to this simple gator-clip approach is that classrooms might not allow soldering, or a lesson&nbsp;might not have time for assembling parts on a breadboard. Or it’s just fun showing off.

### 

It’s not in there. And unless you’re actually using a really&nbsp;old CRT telly, it’s probably not necessary. Most, if not all, LCD monitors that handle composite video will automatically detect and adapt to the video signal, so NTSC is fine. This is true even if you are in a "PAL zone" like Europe!

### 

Composite color video is _insane_ and would require a DAC _orders of magnitude_ faster. Let’s see where microcontrollers are in a few years!

# DAC Hacks for Circuit Playground Express & other ATSAMD21 Boards

## Transmitting AM Radio

…kind of. Temper your expectations. :)

![](https://cdn-learn.adafruit.com/assets/assets/000/041/841/medium800/hacks_OldRadio.jpg?1495255873)

Another task we can use this fast DAC for is generating **AM radio** waveforms, which can be heard on a regular AM receiver&nbsp;tuned to the right frequency and held _very close by_ (power is limited and an ideal antenna is impractically long, but it’s a fun proof of concept).

This too requires a library:

[Download Adafruit_AMRadio Library](https://github.com/adafruit/Adafruit_AMRadio/archive/master.zip)
After the Adafruit\_AMRadio library is installed, there are a couple of example sketches. One plays the Jeopardy theme song over the AM 540 KHz frequency, the other plays a Godzilla roar sound.

Clip a test lead or connect a length of wire to **pin A0** as a makeshift **antenna**. Just one end…the other is left unconnected.&nbsp;This is far from an optimal antenna, but we need _something_ there.

An _ideal_ antenna would be something like 450&nbsp;feet long…clearly that’s not gonna happen. The test lead will do fine.

![hacks_gator-antenna.jpg](https://cdn-learn.adafruit.com/assets/assets/000/041/842/medium640/hacks_gator-antenna.jpg?1495261669)

# Creating New Radio Projects
To use the library, add this line at the top of your code:

```auto
#include &lt;Adafruit_AMRadio.h&gt;
```

Before the setup() function, declare a global object of type **Adafruit\_AMRadio:**

```auto
Adafruit_AMRadio radio;
```

Then, inside your setup() function, call the object’s begin() function to start it running. By default this will transmit at 540 KHz, but you can optionally pass an integer argument, the desired frequency in Hertz:

```auto
radio.begin(530000); // Transmit at 530 KHz instead
```

Try to keep this **as low as possible** , but still within the AM band (530 to 1700 KHz).

It won’t run at _precisely_ this frequency…the DMA clock has to run at some integer divisor of the 48 MHz CPU clock…so it will pick the closest thing it can muster, which may be a few megahertz to either side. If your AM radio has analog tuning you can dial it in for the best reception, like the old days.

The&nbsp;**tone()** function can be used for playing notes&nbsp;—&nbsp;similar to the normal Arduino tone() function — which accepts&nbsp;a frequency in Hertz and a duration in milliseconds (unlike Arduino’s tone(), the duration is _required_ here). For example, to play **middle C** &nbsp;(262 Hertz) for **one half second** (500 milliseconds):

```auto
radio.tone(262, 500);
```

If you need more granular control over the audio waveform, use the radio.write() function to control the&nbsp;wave directly, passing a value from **0 to 1023** (the library’s equivalent of Arduino’s&nbsp;10-bit analogWrite() function). For example, a neutral level:

```auto
radio.write(512);
```

 **This alone does not generate a sound.** You then need to call write() **repeatedly and quickly** to generate an **audio waveform**. This can be seen in the “zilla” example sketch, which reads from a digitized audio sample stored in program memory and calls the write() function roughly 11,025 times a second.

Any existing code that uses analogWrite(A0) to generate sound through the Circuit Playground speaker can be easily modified to use the radio library instead.

# How It Works
_Amplitude modulation_ (AM) — the earliest method of sound transmission over radio — conveys&nbsp;a relatively low-frequency variable audio wave (such as voice or music, up to a few kilohertz) into a much higher fixed-frequency radio wave (500 KHz or more),&nbsp;called the _carrier wave,_ by…you guessed it…_modulating_ the _amplitude_ of the carrier&nbsp;wave in direct proportion to the sound&nbsp;wave’s shape.

<sub>Image credit: Wikimedia Commons contributor <em>Berserkerus,</em> CC-SA</sub>

![hacks_AmplitudeModulation.gif](https://cdn-learn.adafruit.com/assets/assets/000/041/834/medium640thumb/hacks_AmplitudeModulation.jpg?1495242597)

The DAC is _barely_&nbsp;fast enough to generate a reasonable carrier wave for the lower end of the AM radio band. Our library simply&nbsp;adjusts the peaks and troughs of this wave in response to the Arduino sketch code.

Actually the DAC _isn’t_&nbsp;fast enough for this. We’re cheating! Generating a 540 KHz square wave requires&nbsp;1,080 _kilosamples per second_ from the DAC, but it’s really only rated for 350 Ksps. We simply feed it at the faster rate. This is not harmful in any way to the DAC, the output just isn’t numerically precise until it’s fully “settled” (the 350K rate), and we’re interrupting it before it gets all the way there. It’s reasonably close though.&nbsp;The video library does something similar, but not _quite_ as fast, as that one does require&nbsp;a _little_ more precision.

This is also why it only works toward the lower end of the AM band. As the frequency increases, the DAC output precision decreases.

Zooming _way in_ with an oscilloscope, the 540 KHz carrier wave is visible. Though we’re feeding the DAC a square wave, the slow “settling time”&nbsp;produces this truncated triangle wave.&nbsp;This works to our benefit, as the carrier should ideally be a sine wave, and this is a coarse&nbsp;but acceptable facsimile.

Zooming out a bit, you can see the carrier wave amplitude (height) being modulated by the&nbsp;lower-frequency sound wave.

Zooming out still further, the individual audio samples from a digitized Godzilla roar — 11,050 per second — can be seen. The high-frequency carrier wave is so much smaller by comparison, it appears solid on the scope.

![hacks_scope-am1.png](https://cdn-learn.adafruit.com/assets/assets/000/041/848/medium640/hacks_scope-am1.png?1495322343)

![hacks_scope-am2.png](https://cdn-learn.adafruit.com/assets/assets/000/041/849/medium640/hacks_scope-am2.png?1495322354)

![hacks_scope-am4.png](https://cdn-learn.adafruit.com/assets/assets/000/041/850/medium640/hacks_scope-am4.png?1495322376)

# Limitations

- **Circuit Playground Express speaker is disabled;** tone() and other audio code&nbsp; **will not work** in combination with this
- **Range is extremely limited** , just a few inches — this is “science project” fun and not a serious radio transmitter!
- Limited to **lower AM band** ; example code uses **540 KHz**

Adafruit\_CompositeVideo (on the prior page) and Adafruit\_AMRadio both use the DAC peripheral and the same timer/counter; the two libraries **can not be used&nbsp;at the same time.**

### 

Maybe in some ultra-pedantic interpretation, but the range is _so_ limited (less than a foot) it can’t _possibly_&nbsp;interfere with&nbsp;other receivers or devices, so this shouldn’t be a problem. It’s only “broadcasting” if targeting&nbsp;a wider audience. This is “low-grade noise.”

But hey, if the experiment piques your interest, why not study for an [amateur radio license](https://blog.adafruit.com/2016/04/20/congrats-ladyada-ham-license-and-getting-to-amateur-extra-adafruit-arrl-hamradio/)?


## Featured Products

### Circuit Playground Express

[Circuit Playground Express](https://www.adafruit.com/product/3333)
 **Circuit Playground Express** is the next step towards a perfect introduction to electronics and programming. We've taken the original Circuit Playground Classic and made it even better! Not only did we pack even more sensors in, we also made it even easier to...

In Stock
[Buy Now](https://www.adafruit.com/product/3333)
[Related Guides to the Product](https://learn.adafruit.com/products/3333/guides)
### Adafruit Feather M0 Basic Proto - ATSAMD21 Cortex M0

[Adafruit Feather M0 Basic Proto - ATSAMD21 Cortex M0](https://www.adafruit.com/product/2772)
Feather is the new development board from Adafruit, and like its namesake it is thin, light, and lets you fly! We designed Feather to be a new standard for portable microcontroller cores.

This is the&nbsp; **Feather M0 Basic Proto** ,&nbsp;it has a bunch of prototyping space...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2772)
[Related Guides to the Product](https://learn.adafruit.com/products/2772/guides)
### Adafruit Feather M0 Express

[Adafruit Feather M0 Express](https://www.adafruit.com/product/3403)
At the Feather M0's heart is an ATSAMD21G18 ARM Cortex M0+ processor, clocked at 48 MHz and at 3.3V logic, the same one used in the new&nbsp;[Arduino Zero](https://www.adafruit.com/products/2843). This chip has a whopping 256K of FLASH (8x more than the Atmega328 or 32u4) and...

In Stock
[Buy Now](https://www.adafruit.com/product/3403)
[Related Guides to the Product](https://learn.adafruit.com/products/3403/guides)
### Adafruit METRO M0 Express - designed for CircuitPython

[Adafruit METRO M0 Express - designed for CircuitPython](https://www.adafruit.com/product/3505)
Metro is our series of microcontroller boards for use with the Arduino IDE. This new **Metro M0 Express** board looks a whole lot like our&nbsp;[original Metro 328](https://www.adafruit.com/product/2488), but with a huge upgrade. Instead of the ATmega328, this Metro...

In Stock
[Buy Now](https://www.adafruit.com/product/3505)
[Related Guides to the Product](https://learn.adafruit.com/products/3505/guides)
### Small Alligator Clip Test Lead (set of 12)

[Small Alligator Clip Test Lead (set of 12)](https://www.adafruit.com/product/1008)
Connect this to that without soldering using these handy mini alligator clip test leads. 15" cables with alligator clip on each end, color coded. You get 12 pieces in 6 colors. Strong and grippy, these always come in handy! We often use these in conjunction with a multimeter so we...

Out of Stock
[Buy Now](https://www.adafruit.com/product/1008)
[Related Guides to the Product](https://learn.adafruit.com/products/1008/guides)
### Small Alligator Clip to Male Jumper Wire Bundle - 6 Pieces

[Small Alligator Clip to Male Jumper Wire Bundle - 6 Pieces](https://www.adafruit.com/product/3448)
When working&nbsp;with unusual non-header-friendly surfaces, these handy cables will be your best friends! No longer will you have long, cumbersome strands of alligator clips. These compact jumper cables have a premium male header on one end and a grippy mini alligator clip on the...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3448)
[Related Guides to the Product](https://learn.adafruit.com/products/3448/guides)

## Related Guides

- [Adafruit Feather M0 Express](https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython.md)
- [Adafruit Metro M0 Express](https://learn.adafruit.com/adafruit-metro-m0-express.md)
- [Adafruit Circuit Playground Express](https://learn.adafruit.com/adafruit-circuit-playground-express.md)
- [Halloween Monsters with CRICKIT and Circuit Playground Express](https://learn.adafruit.com/halloween-monsters-with-crickit.md)
- [Using DS18B20 Temperature Sensor with CircuitPython](https://learn.adafruit.com/using-ds18b20-temperature-sensor-with-circuitpython.md)
- [Sensors in MakeCode](https://learn.adafruit.com/sensors-in-makecode.md)
- [CircuitPython Hardware: Charlieplex LED Matrix](https://learn.adafruit.com/micropython-hardware-charlieplex-led-matrix.md)
- [Qu'est-ce que MakeCode?](https://learn.adafruit.com/makecode-fr.md)
- [Color Spinner Camera Ring Light ](https://learn.adafruit.com/camera-ring-light-with-cpx.md)
- [Mystery Box: Crypto Countdown Case](https://learn.adafruit.com/mystery-box-crypto-countdown-case.md)
- [CRICKIT WobblyBot](https://learn.adafruit.com/crickit-wobblybot.md)
- [Controlling a Classic Nintendo R.O.B. Robot Using Circuit Playground Express](https://learn.adafruit.com/controlling-a-classic-nintendo-r-o-b-robot-using-circuit-playground-express.md)
- [Giant Mechanical Keyboard](https://learn.adafruit.com/giant-control-alt-delete.md)
- [CircuitPython-Powered 3-minute Nightlight](https://learn.adafruit.com/circuitpython-powered-gemma-nightlight.md)
- [How to Choose a Microcontroller](https://learn.adafruit.com/how-to-choose-a-microcontroller.md)
- [Textable Sensor with FONA and CircuitPython](https://learn.adafruit.com/textable-sensor-with-fona-and-circuitpython.md)
- [Adafruit Feather M4 Express](https://learn.adafruit.com/adafruit-feather-m4-express-atsamd51.md)
- [LED Festival Coat with Mapping and WLED ](https://learn.adafruit.com/led-festival-coat-with-mapping-and-wled.md)
