element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Simple Music Maker
  • Challenges & Projects
  • Project14
  • Simple Music Maker
  • More
  • Cancel
Simple Music Maker
Blog A Simple Arduino Music Box
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Simple Music Maker to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: jc2048
  • Date Created: 16 May 2018 5:02 PM Date Created
  • Views 14432 views
  • Likes 16 likes
  • Comments 15 comments
  • musicmakerch
  • musictimech
  • ardintermediate
  • arduino_projects
  • arduino_classic
  • arduinoch
  • project14
  • music
  • arduino
Related
Recommended

A Simple Arduino Music Box

jc2048
jc2048
16 May 2018

Introduction

 

Happy Birthday Arduino and Happy Birthday Project14.

 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

My entry to the Open Arduino competition was going to be a music box. I'm too late for that, having missed the deadline, so I'll post the blog in Simple Music Maker instead (and keep my fingers crossed that I don't win a fog machine). As you can hear, it's far from perfect, but it was fun to put together and play with.

 

The Uno is going to synthesize the sounds digitally. There's a small amount of analogue circuitry to convert the digital values to an analogue signal and drive a small loudspeaker with a very simple amplifier.

 

Circuit description

 

The waveform is generated by a R-2R network working as a DAC (digital-to-analog converter) directly from the Arduino port pins.

 

See this series of blogs for more on the R-2R network used as a DAC: Arduino: R-2R Experiment

 

image

 

By its nature, because the digital I/O pins swing between the rails, the output of the DAC is 0 to 5V fullscale. That's too high for what I want here, so I need to reduce the swing to something more manageable. I do that with the first stage (U1) which is an inverting amplifier with a gain of one tenth fifth - that then gets me a maximum swing of half a volt (I changed it after writing this because the original was a bit quiet and then forgot to come back and edit the text). The gain is simply R1/R8. The idea behind the 150pF capacitor is to slow the edges of the DAC output which are very fast and cause the op-amp to ring - it helps, but could be done better. The LM324 is an old bipolar op-amp that can't work up all the way up to the supply rail, and it's probably best to keep everything well clear of ground too, so the first stage also places the signal around 2V. It doesn't matter what the actual, precise level is as long as the signals are in a range where the op-amp can function properly - the audio is ac and at the end of the chain will pass through a capacitor, after which it will be referenced to ground again, so we don't care about arbitrary dc offsets prior to that.

 

Following the attenuator, there's a low-pass filter which comprises op-amp U4 and the passive components around it. It's a third-order Sallen-Key filter. This smoothes the waveform and removes the steps at the sampling rate. I didn't design this from scratch, instead I copied an existing design and scaled the resistor values to modify the cut-off frequency. The op-amp is configured as a follower and there's a dc path from the previous stage to the non-inverting input, so the output will still be centred about 2V.

 

The final stage, comprising U2 and the transistors, is a simple (and somewhat crude) power amplifier. The op-amp can't manage enough current to directly drive an 8 ohm loudspeaker, so the transistors lend a hand. The transistors are configured as emitter followers in a push-pull arrangement. To increase the output voltage the op-amp lifts the base of T1, T2 will naturally be off in this situation, and to decrease the output voltage, the op-amp lowers the base voltage of T2, where T1 will be off. The two diodes drop slightly less than the Vbe drops of the transistors and reduce the distance that the op-amp output has to swing when it changes over from one transistor to the other - that reduces the distortion that would otherwise occur because of the slew rate of the op-amp limiting the rate at which its output can change. The whole output stage is within the feedback loop of the op-amp and because it's wired as a follower the voltage at the loudspeaker should be the same as the filter output. There's still a little crossover distortion - a designer of hi-fi power amplifiers would die of shame if their amplifier has these kind of specs - but for a simple Arduino project it's fine.

 

This is what the simulator shows for the overall frequency response:

 

image

 

The output capacitor is there to give a signal at the loudspeaker that swings about ground and gives an avarage of zero - it's not good to have a permanent bias on a loudspeaker. The capacitor forms a high-pass filter with the load resistance (8 ohms) and for the cut-off frequency to be reasonable it needs to be a fairly high value. The 470u here gives a cut-off of about 100Hz. Not Hi-Fi quality, but I don't suppose anyone will worry about that - this isn't intended as a high-fidelity music box.

 

Build

 

As with the R-2R experiments, I built this one on a piece of tri-pad board.

 

Here's the board as I built it:

 

image

 

image

 

 

Testing

 

The starting point for the testing was to simply use the sketches I'd done previously for the audio generator experiments.

 

Here are some traces from the board.

 

This shows a sweep from 20Hz to 20kHz and you can see the way the filter slopes off from about 10kHz upwards:

 

image

 

This is the waveform at the loudspeaker terminals (440Hz) - it's kind of sine-like. The little steps on the slopes of the sinewave are the points where the op-amp is frantically trying to get its output to the right place to effect the changeover between the two transistors.

 

image

 

Music Box Sketch

 

Finally, here's the sketch to play the tune (the include at the start is of arduino.h):

 

/* Arduino Music Box */
#include 
unsigned int tableOffset = 0;          // wave table index
unsigned int noteTime = 0xc35;         // note duration count
volatile unsigned int tableStep = 0;
int i=0;
unsigned int tuneNotes[] = {
    343,0x61c5,
    385,0x61bf,
    343,0x61c5,
    385,0x61bf,
    343,0x61c5,
    385,0x61bf,
    343,0xc38b,
    343,0x61c5,
    306,0x61e2,
    288,0x61c7,
    229,0x61d1,
    192,0x6155,
    306,0x6177,
    288,0xc38e,
    171,0x620f,
    192,0x6155,
    229,0x61d1,
    257,0x619e,
    288,0x61c7,
    306,0x61e2,
    343,0xc38b,
    343,0x61c5,
    288,0x61c7,
    229,0x61d1,
    306,0x61e2,
    257,0x619e,
    257,0x619e,
    229,0xc3a2,
    0,0
    };
 
//
//  --- Sine table - generated by sineTable.exe 
//
unsigned int sineTable[512] = {
   0x8000,0x8192,0x8324,0x84b6,0x8647,0x87d9,0x896a,0x8afb,0x8c8b,0x8e1b,0x8fab,0x9139,0x92c8,0x9455,0x95e2,0x976d,
   0x98f8,0x9a82,0x9c0b,0x9d93,0x9f19,0xa09f,0xa223,0xa3a6,0xa528,0xa6a8,0xa826,0xa9a3,0xab1f,0xac98,0xae11,0xaf87,
   0xb0fb,0xb26e,0xb3de,0xb54d,0xb6ba,0xb824,0xb98c,0xbaf2,0xbc56,0xbdb8,0xbf17,0xc073,0xc1ce,0xc325,0xc47a,0xc5cd,
   0xc71c,0xc869,0xc9b4,0xcafb,0xcc3f,0xcd81,0xcebf,0xcffb,0xd133,0xd269,0xd39b,0xd4ca,0xd5f5,0xd71d,0xd842,0xd964,
   0xda82,0xdb9d,0xdcb4,0xddc7,0xded7,0xdfe3,0xe0ec,0xe1f1,0xe2f2,0xe3ef,0xe4e8,0xe5dd,0xe6cf,0xe7bd,0xe8a6,0xe98c,
   0xea6d,0xeb4a,0xec24,0xecf9,0xedca,0xee96,0xef5f,0xf023,0xf0e2,0xf19e,0xf255,0xf307,0xf3b5,0xf45f,0xf504,0xf5a5,
   0xf641,0xf6d9,0xf76c,0xf7fa,0xf884,0xf909,0xf98a,0xfa05,0xfa7d,0xfaef,0xfb5d,0xfbc5,0xfc29,0xfc89,0xfce3,0xfd39,
   0xfd8a,0xfdd6,0xfe1d,0xfe5f,0xfe9d,0xfed5,0xff09,0xff38,0xff62,0xff87,0xffa7,0xffc2,0xffd8,0xffe9,0xfff6,0xfffd,
   0xffff,0xfffd,0xfff6,0xffe9,0xffd8,0xffc2,0xffa7,0xff87,0xff62,0xff38,0xff09,0xfed5,0xfe9d,0xfe5f,0xfe1d,0xfdd6,
   0xfd8a,0xfd39,0xfce3,0xfc89,0xfc29,0xfbc5,0xfb5d,0xfaef,0xfa7d,0xfa05,0xf98a,0xf909,0xf884,0xf7fa,0xf76c,0xf6d9,
   0xf641,0xf5a5,0xf504,0xf45f,0xf3b5,0xf307,0xf255,0xf19e,0xf0e2,0xf023,0xef5f,0xee96,0xedca,0xecf9,0xec24,0xeb4a,
   0xea6d,0xe98c,0xe8a6,0xe7bd,0xe6cf,0xe5dd,0xe4e8,0xe3ef,0xe2f2,0xe1f1,0xe0ec,0xdfe3,0xded7,0xddc7,0xdcb4,0xdb9d,
   0xda82,0xd964,0xd842,0xd71d,0xd5f5,0xd4ca,0xd39b,0xd269,0xd133,0xcffb,0xcebf,0xcd81,0xcc3f,0xcafb,0xc9b4,0xc869,
   0xc71c,0xc5cd,0xc47a,0xc325,0xc1ce,0xc073,0xbf17,0xbdb8,0xbc56,0xbaf2,0xb98c,0xb824,0xb6ba,0xb54d,0xb3de,0xb26e,
   0xb0fb,0xaf87,0xae11,0xac98,0xab1f,0xa9a3,0xa826,0xa6a8,0xa528,0xa3a6,0xa223,0xa09f,0x9f19,0x9d93,0x9c0b,0x9a82,
   0x98f8,0x976d,0x95e2,0x9455,0x92c8,0x9139,0x8fab,0x8e1b,0x8c8b,0x8afb,0x896a,0x87d9,0x8647,0x84b6,0x8324,0x8192,
   0x8000,0x7e6d,0x7cdb,0x7b49,0x79b8,0x7826,0x7695,0x7504,0x7374,0x71e4,0x7054,0x6ec6,0x6d37,0x6baa,0x6a1d,0x6892,
   0x6707,0x657d,0x63f4,0x626c,0x60e6,0x5f60,0x5ddc,0x5c59,0x5ad7,0x5957,0x57d9,0x565c,0x54e0,0x5367,0x51ee,0x5078,
   0x4f04,0x4d91,0x4c21,0x4ab2,0x4945,0x47db,0x4673,0x450d,0x43a9,0x4247,0x40e8,0x3f8c,0x3e31,0x3cda,0x3b85,0x3a32,
   0x38e3,0x3796,0x364b,0x3504,0x33c0,0x327e,0x3140,0x3004,0x2ecc,0x2d96,0x2c64,0x2b35,0x2a0a,0x28e2,0x27bd,0x269b,
   0x257d,0x2462,0x234b,0x2238,0x2128,0x201c,0x1f13,0x1e0f,0x1d0d,0x1c10,0x1b17,0x1a22,0x1930,0x1842,0x1759,0x1673,
   0x1592,0x14b5,0x13db,0x1306,0x1235,0x1169,0x10a0,0x0fdc,0x0f1d,0x0e61,0x0daa,0x0cf8,0x0c4a,0x0ba0,0x0afb,0x0a5a,
   0x09be,0x0926,0x0893,0x0805,0x077b,0x06f6,0x0675,0x05fa,0x0582,0x0510,0x04a2,0x043a,0x03d6,0x0376,0x031c,0x02c6,
   0x0275,0x0229,0x01e2,0x01a0,0x0162,0x012a,0x00f6,0x00c7,0x009d,0x0078,0x0058,0x003d,0x0027,0x0016,0x0009,0x0002,
   0x0000,0x0002,0x0009,0x0016,0x0027,0x003d,0x0058,0x0078,0x009d,0x00c7,0x00f6,0x012a,0x0162,0x01a0,0x01e2,0x0229,
   0x0275,0x02c6,0x031c,0x0376,0x03d6,0x043a,0x04a2,0x0510,0x0582,0x05fa,0x0675,0x06f6,0x077b,0x0805,0x0893,0x0926,
   0x09be,0x0a5a,0x0afb,0x0ba0,0x0c4a,0x0cf8,0x0daa,0x0e61,0x0f1d,0x0fdc,0x10a0,0x1169,0x1235,0x1306,0x13db,0x14b5,
   0x1592,0x1673,0x1759,0x1842,0x1930,0x1a22,0x1b17,0x1c10,0x1d0d,0x1e0e,0x1f13,0x201c,0x2128,0x2238,0x234b,0x2462,
   0x257d,0x269b,0x27bd,0x28e2,0x2a0a,0x2b35,0x2c64,0x2d96,0x2ecc,0x3004,0x3140,0x327e,0x33c0,0x3504,0x364b,0x3796,
   0x38e3,0x3a32,0x3b85,0x3cda,0x3e31,0x3f8c,0x40e8,0x4247,0x43a9,0x450d,0x4673,0x47db,0x4945,0x4ab2,0x4c21,0x4d91,
   0x4f04,0x5078,0x51ee,0x5367,0x54e0,0x565c,0x57d9,0x5957,0x5ad7,0x5c59,0x5ddc,0x5f60,0x60e6,0x626c,0x63f4,0x657d,
   0x6707,0x6892,0x6a1d,0x6baa,0x6d37,0x6ec6,0x7054,0x71e4,0x7374,0x7504,0x7695,0x7826,0x79b8,0x7b49,0x7cdb,0x7e6d};
void setup() {
  
  // set the digital pins as outputs:
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
 
  // timer 2 set up
  cli();                  // disable interrupts
  TCCR2A = 0;             // control register all 0
  TCCR2B = 0;             // control register all 0
  TCNT2 = 0;              // set count to 0
  OCR2A = 159;            // period = 160 x 1/16MHz = 10uS
  TCCR2A |= (1 << WGM21); // mode is clear on match
  TCCR2B |= (1 << CS20);  // no prescaler   
  TIMSK2 |= (1 << OCIE2A);  // enable interrupt on match
  sei();                  // enable interrupts
}
ISR(TIMER2_COMPA_vect) {
  if(tableStep == 0) {
    PORTD = 0x80;
    noteTime = noteTime - 1;
    if(noteTime==0) {
      tableStep = tuneNotes[i++];
      noteTime = tuneNotes[i++];
      tableOffset = 0;
      }
    }
  else {
    tableOffset = tableOffset + tableStep;
    PORTD = (sineTable[tableOffset >> 7]) >> 8;
    noteTime = noteTime - 1;
    if(noteTime==0) {
      tableOffset = 0;
      tableStep = 0;
      noteTime = 0xc35;
      if (tuneNotes[i]==0)
        i=0;
      }
    }
}
void loop() {
}

 

The code is a bit clunky but it's a starting point for experimenting with. This is a rather fast version of 'Twinkle, Twinkle, Little Star' (I know it doesn't sound much like it, but really it is). This is with the waveform table containing a sine wave, so it has an electronic quality to it, and there's no envelope control, so the notes just slam in and out. The note table is arranged in pairs, first the note and then the duration. The note is the step value for the waveform table, the duration is the number of 10uS intervals. Having the duration in terms of the steps might seem awkward (and it is) but when I first tried it I got a lot of nasty clicking from having abrupt terminations part way through a sine wave cycle, so these values have been arranged to finish close to the point where it would cross zero.

 

For an actual music box, it would probably want to play through once on being powered up and then turn itself off - at the moment it repeats endlessly.

 

There are follow-on blogs here:

 

Simple Arduino Music Box: Voices

Simple Arduino Music Box: Chords

Simple Arduino Music Box: Envelopes

Simple Arduino Music Box: Chimes

  • Sign in to reply

Top Comments

  • jc2048
    jc2048 over 7 years ago in reply to shabaz +7
    See if you can guess what film this is from. players.brightcove.net/.../index.html The tune goes a bit wrong at the end. I don't think my new assistant is very impressed - either with my lack of cinematography…
  • jc2048
    jc2048 over 7 years ago in reply to jw0752 +7
    Thanks John. A further bonus is that I'm now a Tesla (the points from this just tipped me over the 50,000 limit). Are the rumours true that I now get a free trip to Mars?
  • jc2048
    jc2048 over 7 years ago in reply to 14rhb +5
    This is what it looks like from the end, just in case anyone's interested. If I moved the tant that's almost colliding with the microcontroller, the top board could come down 5mm, or so.
  • jw0752
    jw0752 over 7 years ago in reply to jc2048

    Hi Jon,

     

    Congratulations on Tesla. I have always admired Tesla's genius. As far as the trip to Mars, I would not hold my breath. They are still trying to organize a meet and greet in Chicago that probably won't happen.

     

    John

    • Cancel
    • Vote Up +4 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • jc2048
    jc2048 over 7 years ago in reply to shabaz

    Another platform that people might like to consider would be the ST processor on one of the Nucleo boards that has an on-board DAC and a couple of in-built op-amps. I'd probably have looked at that if I'd originally set out to do Simple Music rather than the Open Arduino challenge. That might only need a couple of transistors, some passives, and the loudspeaker.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • jc2048
    jc2048 over 7 years ago in reply to jw0752

    Thanks John. A further bonus is that I'm now a Tesla (the points from this just tipped me over the 50,000 limit). Are the rumours true that I now get a free trip to Mars?

    • Cancel
    • Vote Up +7 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • jw0752
    jw0752 over 7 years ago

    Hi Jon,

    Thanks for posting this great project even though you were past the dead line. It is very impressive, the amount of work and the quality that you put into it. Doing things well has its own rewards but the respect of your audience is a nice extra bonus.

    John

    • Cancel
    • Vote Up +4 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz over 7 years ago in reply to jc2048

    That's really awesome : ) It's very recognisable and sounds great : )

    I'll hopefully try on a FRDM board too (although that's easier. You're on a way more constrained platform).

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube