Using the PCM510x I2S DAC with Arduino involves wiring up the DAC and running the provided example code.
Wiring
You can power the DAC with 3.3 to 5VDC, however, the data lines are 3.3V logic only. You'll want to use a 3.3V logic level board.
Here is an Adafruit Feather RP2040 wired up to the DAC:
- Board 3.3V to DAC VIN (red wire)
- Board GND to DAC GND (black wire)
- Board D9 to DAC BCK (yellow wire)
- Board D10 to DAC WSEL (green wire)
- Board D11 to DAC DIN (blue wire)
- DAC 3.5mm output to line-level speaker
No additional libraries are required for these examples.
// SPDX-FileCopyrightText: 2016 Sandeep Mistry // SPDX-FileCopyrightText: 2022 Earle F. Philhower, III // SPDX-FileCopyrightText: 2023 Ladyada for Adafruit Industries // // SPDX-License-Identifier: MIT /* This example generates a square wave based tone at a specified frequency and sample rate. Then outputs the data using the I2S interface to a MAX08357 I2S Amp Breakout board. created 17 November 2016 by Sandeep Mistry modified for RP2040 by Earle F. Philhower, III <[email protected]> bool setBCLK(pin_size_t pin); - This assigns two adjacent pins - the pin after this one (one greater) is the WS (word select) signal, which toggles before the sample for each channel is sent bool setDATA(pin_size_t pin); - Sets the DOUT pin, can be any valid GPIO pin */ #include <I2S.h> // Create the I2S port using a PIO state machine I2S i2s(OUTPUT); // GPIO pin numbers on Feather RP2040 #define pBCLK D9 // BITCLOCK #define pWS D10 // LRCLOCK #define pDOUT D11 // DATA const int frequency = 440; // frequency of square wave in Hz const int amplitude = 500; // amplitude of square wave const int sampleRate = 16000; // 16 KHz is a good quality const int halfWavelength = (sampleRate / frequency); // half wavelength of square wave int16_t sample = amplitude; // current sample value int count = 0; void setup() { Serial.begin(115200); while (!Serial) delay(10); Serial.println("I2S simple tone"); i2s.setBCLK(pBCLK); i2s.setDATA(pDOUT); i2s.setBitsPerSample(16); // start I2S at the sample rate with 16-bits per sample if (!i2s.begin(sampleRate)) { Serial.println("Failed to initialize I2S!"); while (1); // do nothing } } void loop() { if (count % halfWavelength == 0) { // invert the sample every half wavelength count multiple to generate square wave sample = -1 * sample; } // write the same sample twice, once for left and once for the right channel i2s.write(sample); i2s.write(sample); // increment the counter for the next sample count++; }
Once you have uploaded the sketch to your board, you'll hear a tone.
You can change the frequency (pitch) of the tone by updating the frequency
variable.
const int frequency = 440; // frequency of square wave in Hz
This example plays a PCM audio file when the Boot button is pressed. Check out this Python script to convert WAV files to PCM files.
Click the button below to download the source code and header file. Unzip it, and open it with the Arduino IDE.
When you open the code in the Arduino IDE, you will see the Arduino sketch code in one tab, and the header file in a second tab.
Once you've uploaded the sketch to your board, you'll hear the startup tone play in a loop with a short pause.
// SPDX-FileCopyrightText: 2023 Ladyada for Adafruit Industries // // SPDX-License-Identifier: MIT /* This example plays a 'raw' PCM file from memory to I2S */ #include <I2S.h> #include "startup.h" // audio file in flash // Create the I2S port using a PIO state machine I2S i2s(OUTPUT); // GPIO pin numbers on Feather RP2040 #define pBCLK D9 // BITCLOCK #define pWS D10 // LRCLOCK #define pDOUT D11 // DATA void setup() { Serial.begin(115200); while (!Serial) delay(10); Serial.println("I2S playback demo"); } void loop() { } void setup1() { i2s.setBCLK(pBCLK); i2s.setDATA(pDOUT); i2s.setBitsPerSample(16); } void loop1() { // the main loop will tell us when it wants us to play! play_i2s(startupAudioData, sizeof(startupAudioData), startupSampleRate); delay(1000); } void play_i2s(const uint8_t *data, uint32_t len, uint32_t rate) { // start I2S at the sample rate with 16-bits per sample if (!i2s.begin(rate)) { Serial.println("Failed to initialize I2S!"); delay(500); i2s.end(); return; } for(uint32_t i=0; i<len; i++) { uint16_t sample = (uint16_t)data[i] << 6; // our data is 10 bit but we want 16 bit so we add some gain // write the same sample twice, once for left and once for the right channel i2s.write(sample); i2s.write(sample); } i2s.end(); }
Page last edited March 10, 2025
Text editor powered by tinymce.