Today I decided to test the AD7840 14 bit DAC that I had bought long time ago for telephone project. I wanted to learn, utilize it and perhaps incoporate to build independent communication system with Arduino AM transmitter and Arduino AM receiver. This DAC IC could be used to generate carrier signal but I am not sure and today I am testing this. Also one question is whether there is any real benefit to use external DAC because Arduino can generate sine wave in PWM mode or CTC mode by using external filter.
The AD7840 DAC IC pinout and internal block diagram is shown below.
This DAC supports both serial and parallel data transfer from the microcontroller or microprocessor. But the parallel interface is troublesome to make on breadboard and also takes lot of Arduino pins. Luckily it supports the serial data transfer using the SPI protocol also called the 3 wire interface.
Pin Connections between Arduino Nano and AD7840 DAC:
Here’s how to connect the AD7840 to the Arduino Nano using SPI:
-
AD7840 Pins:
-
VDD: Connect to 5V (or 3.3V, depending on the DAC version).
-
GND: Connect to Ground (GND).
-
SCLK (Serial Clock): Connect to Pin 13 (Arduino Nano, SCK).
-
SDI (Serial Data Input): Connect to Pin 11 (Arduino Nano, MOSI).
-
CS (Chip Select): Connect to Pin 10 (Arduino Nano).
-
LDAC (Load DAC): Connect to Ground (Optional, can be controlled to update DAC data manually).
-
VOUT: Connect to the analog output where you want the analog signal.
-
-
Arduino Nano Pins:
-
Pin 13: SCK (Serial Clock) – Connect to AD7840 SCLK.
-
Pin 11: MOSI (Master Out Slave In) – Connect to AD7840 SDI.
-
Pin 10: CS (Chip Select) – Connect to AD7840 CS.
-
Pin A0: (Optional) You can use an analog input pin to control the DAC output, for example, reading from a potentiometer.
-
Arduino Nano Code to Generate a Sine Wave (using SPI to interface with AD7840):
The following Arduino code generates sine wave data and sends to external DAC.
#include <SPI.h>
// Pin for DAC Chip Select (CS)
const int dacCS = 10; // Pin 10 as chip select for DAC (e.g., AD7840)
// Sine wave lookup table (values between 0 and max DAC value, depending on resolution)
const uint16_t sineTable[] = {
2047, 2286, 2502, 2685, 2837, 2953, 3032, 3073,
3073, 3032, 2953, 2837, 2685, 2502, 2286, 2047
};
const int dacBits = 14; // Set your DAC resolution here (12, 14, 16, etc.)
const int sineFrequency = 1000; // Target sine wave frequency in Hz
const int samplesPerCycle = sizeof(sineTable) / sizeof(sineTable[0]);
unsigned long previousMicros = 0; // Time of previous sample
unsigned long intervalMicros = 0; // Microsecond interval between samples
int sampleIndex = 0;
void setup() {
SPI.begin();
pinMode(dacCS, OUTPUT);
digitalWrite(dacCS, HIGH); // Deactivate DAC
// Optional: adjust SPI settings here if needed
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
Serial.begin(9600);
intervalMicros = 1000000UL / (sineFrequency * samplesPerCycle); // microseconds between samples
}
void loop() {
unsigned long now = micros();
if (now - previousMicros >= intervalMicros) {
previousMicros = now;
writeDAC(sineTable[sampleIndex], dacBits);
sampleIndex++;
if (sampleIndex >= samplesPerCycle) sampleIndex = 0;
}
}
// Send data to DAC (with adjustable resolution)
void writeDAC(uint32_t value, uint8_t bits) {
uint8_t msb_width = 8;
uint8_t lsb_width = bits - msb_width;
uint8_t msb = value >> lsb_width;
uint8_t lsb = value & ((1 << lsb_width) - 1);
digitalWrite(dacCS, LOW);
SPI.transfer(msb);
SPI.transfer(lsb << (8 - lsb_width)); // Left-justify LSB
digitalWrite(dacCS, HIGH);
}
How to use the program:
-
Just change
dacBits
to match your DAC (e.g.,12
,14
, or16
). -
Ensure your
sineTable[]
values are scaled to match the maximum value for that DAC:-
12-bit DAC → max = 4095
-
14-bit DAC → max = 16383
-
16-bit DAC → max = 65535
-
Simulation Video
See the simulation video of how the AD7840 14 bit DAC works with Arduino.
You now have a diy Arduino based flexible sine wave generator with SPI support for any common N-bit DAC which you can use for communication projects. I want to make Arduino AM transmitter and receiver.