Skip to content

Adds Toms UNO R4 DAC examples to the AnalogWave core library #47

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
Plays a tone in response to a potentiometer
formula from https://newt.phys.unsw.edu.au/jw/notes.html
and https://en.wikipedia.org/wiki/MIDI_tuning_standard:

the MIDI protocol divides the notes of an equal-tempered scale into
128 possible note values. Middle A is MIDI note value 69. There is
a formula for converting MIDI note numbers (0-127) to pitches. This sketch
reduces that to the notes 21 - 108, which are the 88 keys found on a piano:

frequency = 440 * ((noteNumber - 69) / 12.0)^2

You can see this applied in the code below.

circuit:
* audio amp (LM386 used for testing) input+ attached to A0
* audio amp input- attached to ground
* 4-8-ohm speaker attached to amp output+
* Potentiometer connected to pin A5

created 18 Dec 2018
modified 3 Jul 2023
by Tom Igoe
*/

// include the AnalogWave library:
#include "analogWave.h"
analogWave wave(DAC);

// middle A is the reference frequency for an
// equal-tempered scale. Set its frequency and note value:
#define NOTE_A4 69 // MIDI note value for middle A
#define FREQ_A4 440 // frequency for middle A

const int speakerPin = A0; // the pin number for the speaker
void setup() {
Serial.begin(9600);
wave.sine(10);
}
void loop() {
// convert sensor reading to 21 - 108 range
// which is the range of MIDI notes on an 88-key keyboard
// (from A0 to C8):
int sensorReading = analogRead(A5);
int noteValue = map(sensorReading, 0, 1023, 21, 108);
// then convert to frequency:
float frequency = FREQ_A4 * pow(2, ((noteValue - NOTE_A4) / 12.0));
int freq = int(frequency);
// turn the speaker on:
wave.freq(freq);
Serial.print("note value: "+ String(noteValue) + " freq: ");
Serial.println(freq);
delay(500);
}
81 changes: 81 additions & 0 deletions libraries/AnalogWave/examples/DACJacques/DACJacques.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
DAC Melody player

Generates a series of tones from MIDI note values
using the Uno R4 DAC and the AnalogWave Library.
The melody is "Frere Jacques"

circuit:
* audio amp (LM386 used for testing) input+ attached to A0
* audio amp input- attached to ground
* 4-8-ohm speaker attached to amp output+
* Potentiometer connected to pin A5

created 13 Feb 2017
modified 3 Jul 2023
by Tom Igoe
*/
#include "analogWave.h"
analogWave wave(DAC);

#define NOTE_A4 69 // MIDI note value for middle A
#define FREQ_A4 440 // frequency for middle A

// the tonic, or first note of the key signature for the song:
int tonic = 65;
// the melody sequence. Note values are relative to the tonic:
int melody[] = {1, 3, 5, 1,
1, 3, 5, 1,
5, 6, 8, 5, 6, 8,
8, 10, 8, 6, 5, 1,
8, 10, 8, 6, 5, 1,
1, -4, 1,
1, -4, 1
};
// the rhythm sequence. Values are 1/note, e.g. 4 = 1/4 note:
int rhythm[] = {4, 4, 4, 4,
4, 4, 4, 4,
4, 4, 2,
4, 4, 2,
8, 8, 8, 8, 4, 4,
8, 8, 8, 8, 4, 4,
4, 4, 2,
4, 4, 2
};
// which note of the melody to play:
int noteCounter = 0;

int bpm = 120; // beats per minute
// duration of a beat in ms
float beatDuration = 60.0 / bpm * 1000;

void setup() {
// start the sine wave generator:
wave.sine(10);
}

void loop() {
// current note is an element of the array:
int currentNote = melody[noteCounter] + tonic;
// play a note from the melody:
// convert MIDI note number to frequency:
float frequency = FREQ_A4 * pow(2, ((currentNote - NOTE_A4) / 12.0));

// all the notes in this are sixteenth notes,
// which is 1/4 of a beat, so:
float noteDuration = beatDuration * (4.0 / rhythm[noteCounter]);
// turn the note on:
wave.freq(frequency);
// tone(speakerPin, frequency, noteDuration * 0.85);
// keep it on for the appropriate duration:
delay(noteDuration * 0.85);
wave.stop();
delay(noteDuration * 0.15);
// turn the note off:
// noTone(speakerPin);
// increment the note number for next time through the loop:
noteCounter++;
// keep the note in the range from 0 - 32 using modulo:
noteCounter = noteCounter % 32;

}