Musical doorbell-style Star Wars on the Arduino

Hello, recently I said yes and pointed to the video, as you can flash Attiny13 using Arduino , and now show the practical use it.

I have to say, Fyuz, firmware as a hex-file C code, a sketch for the Arduino IDE, files for Proteus 7 can be downloaded at the end of the article.

Well, that really pull, show how it works:



Long wanted to afford such a musical doorbell, so that when you press play march Empire (Imperial March or Darth Vader's Theme) from «Звёздных Wars », really like this tune.


As the name implies the video above, the main component of the device - microcontroller Attiny13 , its application has made it possible to make the size of the board several times Smaller than a matchbox:

Dimensions board

And now all the attached:



Power range from about 2 to 6, that is, from two to four batteries size AA, although ideally would provide voltage 3-4 V, i.e. for this purpose is ideal lithium ion battery of a mobile phone or a battery 18650 format, however, it is desirable that it be protected with, since I have not yet implemented any protection against deep discharge.

Well, I will say a few words on the circuit design:

The scheme looks like this (Proteus files attached to the end of the article, you can even do not collect on maketke):

painted in Proteus'e



Since the microcontroller alone can not pull enough volume to be heard throughout the house call, I added NPN transistor 2N3904 < / a>, a pretty common transistor, in principle, can approach any transistor that pulls speaker, in my case the transistor capacity of 100 mA.
When using 3 AA batteries format transistor slightly warmed, using two - volume remained at a good level but the transistor was a little warm.
Resistor R2 - Standard Installation for microcontroller provides protection against accidental resets the microcontroller, in principle, should work without it, the resistor R1 serves to limit the current to the base of the transistor.
The photo shows more protective diode protects it from negligence, namely, reverse polarity, in my case, reversed very quickly bring down the microcontroller, with quite possible as fireworks and sound effects. By the way, in the diagram below, I forgot to specify it, you can use any diode that is rated for the voltage of 10 V and a current of 200 mA, becoming successively entry fees or minus or plus, minus for me.
Speaker of the old Dial up modem Zyxel, by the way, about the Dial up modems this company has a well-known anecdote:

Joke Sit two hackers, and the room comes a cat. One hacker asks:
- Your cat?
- Yes, my. Zuhel name!
- Why Zuhel?
- Look here. Takes the broom, pokes him in the cat and says, "Zuhel, connection !!!" Cat:
- Pshshshshshshshshshshshshshsh!



The code I have to say, , more precisely found in the vast youtube, here's the video itself:



Under the video has a link to , here it is:

code from the description to the video
 & lt; code class = & quot; cpp & quot; & gt; #include & lt; avr / pgmspace.h & gt; // Bytartakynov // programmed for ATtiny13 in Arduino IDE using core13 http://sourceforge.net/projects/ard-core13/ #define PIN_LED 1 #define PIN_BUZZER 0 #define COUNT_NOTES 39 word frequences [COUNT_NOTES] PROGMEM = {392 , 392, 392, 311, 466, 392, 311, 466, 392, 587, 587, 587, 622, 466, 369, 311, 466, 392, 784, 392, 392, 784, 739, 698, 659, 622 , 659, 415, 554, 523, 493, 466, 440, 466, 311, 369, 311, 466, 392}; word durations [COUNT_NOTES] PROGMEM = {350, 350, 350, 250, 100, 350, 250, 100, 700, 350, 350, 350, 250, 100, 350, 250, 100, 700, 350, 250, 100, 350, 250, 100, 100, 100, 200, 100, 350, 250, 100, 100, 100, 200, 100, 350, 250, 100, 750}; void setup () {pinMode (PIN_LED, OUTPUT); pinMode (PIN_BUZZER, OUTPUT); } Void loop () {for (byte i = 0; i & lt; COUNT_NOTES; i ++) {buzz (PIN_BUZZER, pgm_read_word (& amp; (frequences [i])), 2 * pgm_read_word (& amp; (durations [i])) ); delay (100); } Delay (3000); } Void buzz (unsigned char pin, word frequencyInHertz, word timeInMilliseconds) {long delayAmount = (long) (long (1000000) / (long) frequencyInHertz); long loopTime = (long) (((long) timeInMilliseconds * 500) / delayAmount); for (long i = 0; i & lt; loopTime; i ++) {digitalWrite (pin, HIGH); delayMicroseconds (delayAmount); digitalWrite (pin, LOW); delayMicroseconds (delayAmount); }} & Lt; / code & gt;  pre> The size of the sketch in binary code: 946 bytes (of 1024 bytes maximum) 


As you can see, there are two arrays frequences - translated from the English frequency and durations - duration, all data type word, PROGMEM - data is stored in flash memory microcontroller (without the use of the library pgmspace.h will not work) Well, there is a frequency generator buzz () which takes three parameters - the pin, which is generated frequency, the second - the frequency in hertz, and the third - the duration in milliseconds.
This code must be Arduino compatible and work even on Arduino Uno, Arduino Nano or Arduino Pro Mini and other well and Duino.

As you can hear in the video, the sound of my videos is slightly different from the second video, the fact that I'm a little change the duration of notes and three times as popular method of "scientific spear", raised the frequency, since such a small speaker like me bad plays those frequencies that were originally, and add a button, what doorbell without buttons?

A little corrected by himself and commented out
 & lt; code class = & quot; cpp & quot; & gt; // Bytartakynov: // http://youtu.be/5R7NeQkVS_8 // and me - vk.com/razniepodelki #define F_CPU 1200000L // frequency in hertz MK #include & lt; avr / pgmspace.h & gt; // Need to PROGMEM #define PIN_BUZZER 2 // PB2 Speaker #define BUTTON 4 // PB4 button #define COUNT_NOTES 39 // number of notes word frequences [COUNT_NOTES] PROGMEM = {// here are the frequency 392, 392, 392, 311, 466, 392, 311, 466, 392, 587, 587, 587, 622, 466, 369, 311, 466, 392, 784, 392, 392, 784, 739, 698, 659, 622, 659, 415, 554, 523, 493, 466, 440, 466, 311, 369, 311, 466, 392}; word durations [COUNT_NOTES] PROGMEM = {// here their durations 350, 350, 350, 250, 100, 350, 250, 100, 700, 350, 350, 350, 250, 100, 350, 250, 100, 700, 350 , 250, 100, 350, 250, 100, 100, 100, 450, 150, 350, 250, 100, 100, 100, 450, 150, 350, 250, 100, 750}; // Void setup () // {int main (void) // this is an analogue void setup (), to save space {pinMode (PIN_BUZZER, OUTPUT); // Initialize the pins pinMode (BUTTON, INPUT); // Connect a pullup resistor digitalWrite (BUTTON, HIGH); // Button to return the // LOW when you //} // void loop () // {while (1) {// analogue void loop () (infinite loop) if (digitalRead (BUTTON) == LOW) {/ / when the button is pressed for (byte i = 0; i & lt; COUNT_NOTES; i ++) // actually lose tune {buzz (PIN_BUZZER, pgm_read_word (& amp; (frequences [i])) * 3, 2 * pgm_read_word (& amp; (durations [i]))); // Was originally: // buzz (PIN_BUZZER, pgm_read_word (& amp; (frequences [i])), 2 * pgm_read_word (& amp; (durations [i]))); // But I multiplied frequency 3 // (pgm_read_word (& amp; (frequences [i])) * 3) // make it louder audible on the small speaker // delay (100); // Do not need}} // delay (3000); // And this} // these lines need return 0; // Int main (void)} // and while (1) void buzz (unsigned char pin, word frequencyInHertz, word timeInMilliseconds) // in fact it {// frequency generator long delayAmount = (long) (long (1000000) / (long) frequencyInHertz); // Parameter has three long loopTime = (long) (((long) timeInMilliseconds * 500) / delayAmount); // 1 - pin for (long i = 0; i & lt; loopTime; i ++) // 2 - {// frequency 3 - duration digitalWrite (pin, HIGH); // Generate the desired frequency pulses delayMicroseconds (delayAmount); digitalWrite (pin, LOW); delayMicroseconds (delayAmount); }} & Lt; / code & gt;  pre> The size of the sketch in binary code: 976 bytes (of 1024 bytes maximum) 


As you can see, adding the response when you press the button exceeds 1024 bytes, and had to insert pieces of C code to fit in attiny13.
Frequency of raised lines buzz (PIN_BUZZER, pgm_read_word (& (frequences [i])) * 3, 2 * pgm_read_word (& (durations [i]))); by multiplying the frequency generated as you figure three, this is purely my whim, can not multiply anything at all.

If you are an experienced arduinschik, I think notice in the code that I have made software lift PULLUP resistor to the port PB4.
For those who do not know it is done so:
Exhibit at the input port; Ideas and it logical unit. Now the port will be the voltage is approximately equal to the supply voltage, if this port is shorted to ground, it will change its state from a logical unit to logical zero, with the microcontroller at the same time will not suffer, because it uses an internal resistor whose value 10-100 ohms.
I did it purely to save board space, you can just solder resistor to 10k plus food and the desired port by pressing the button we "attract port to the earth," and it would be logical zero.

Add code to clean AVR-C for labor AVR'schikov:

Code for AVR-C
 & lt; code class = & quot; cpp & quot; & gt; // Bytartakynov: // http://youtu.be/5R7NeQkVS_8 // and me - vk.com/razniepodelki #define F_CPU 1200000UL // frequency in hertz MK #include & lt; avr / io.h & gt; // Library Input Output #include & lt; util / delay.h & gt; // Library for dealing with delays #include & lt; avr / pgmspace.h & gt; // Need to PROGMEM #define PIN_BUZZER 2 // PB2 Speaker #define BUTTON 4 // PB4 button #define COUNT_NOTES 39 // number of notes word frequences [COUNT_NOTES] PROGMEM = {// here are the frequency 392, 392, 392, 311, 466, 392, 311, 466, 392, 587, 587, 587, 622, 466, 369, 311, 466, 392, 784, 392, 392, 784, 739, 698, 659, 622, 659, 415, 554, 523, 493, 466, 440, 466, 311, 369, 311, 466, 392}; word durations [COUNT_NOTES] PROGMEM = {// here their durations 350, 350, 350, 250, 100, 350, 250, 100, 700, 350, 350, 350, 250, 100, 350, 250, 100, 700, 350 , 250, 100, 350, 250, 100, 100, 100, 450, 150, 350, 250, 100, 100, 100, 450, 150, 350, 250, 100, 750}; // Void setup () // {int main (void) // this is an analogue void setup (), to save space {DDRB | = (1 & lt; & lt; PIN_BUZZER); // Port initsyalizatsiya DDRB & amp; = ~ (1 & lt; & lt; BUTTON); // Connect a pullup resistor PORTB | = (1 & lt; & lt; BUTTON); // // This button resets to 0 when you press (zamykinii) //} // void loop () // {while (1) {// analogue void loop () (infinite loop) if (! (PINB & amp; (1 & lt ; & lt; BUTTON))) {// when the button is pressed for (byte i = 0; i & lt; COUNT_NOTES; i ++) // actually lose tune {buzz (pgm_read_word (& amp; (frequences [i])) * 3 2 * pgm_read_word (& amp; (durations [i]))); // Was originally: // buzz (PIN_BUZZER, pgm_read_word (& amp; (frequences [i])), 2 * pgm_read_word (& amp; (durations [i]))); // But I multiplied frequency 3 // (pgm_read_word (& amp; (frequences [i])) * 3) // make it louder audible on the small speaker} // _ delay_ms (100); // For debugging} // _ delay_ms (3000); // For debugging} // these lines need return 0; // Int main (void)} // and while (1) // void buzz (unsigned char pin, word frequencyInHertz, word timeInMilliseconds) void buzz (word frequencyInHertz, word timeInMilliseconds) // in fact it {// frequency generator long delayAmount = (long) (long (1,000,000) / (long) frequencyInHertz); // Parameter has three long loopTime = (long) (((long) timeInMilliseconds * 500) / delayAmount); // 1 - pin for (long i = 0; i & lt; loopTime; i ++) // 2 - {// frequency 3 - duration // digitalWrite (pin, HIGH); // Generate pulses of the desired frequency PORTB | = (1 & lt; & lt; PIN_BUZZER); // To save'll put stitches in C // delayMicroseconds (delayAmount); // Ms delay on the Arduino _delay_us (delayAmount); // In C // digitalWrite (pin, LOW); PORTB & amp; = ~ (1 & lt; & lt; PIN_BUZZER); // DelayMicroseconds (delayAmount); // Ms delay on the Arduino _delay_us (delayAmount); // In C}} & lt; / code & gt;  pre> 

It seems as it should compile without problems, but when you use this code in the Arduino IDE somehow hex file size of at least doubled "The size of the sketch in binary code: 1986 bytes (1024 bytes of the maximum)."
As I found out all this from the use _delay_us (*); although arduinovskaya function delayMicroseconds (*); essentially does the same thing, I think it's Trouble kernel files for tini13, that branch on the :

Hidden Text



Now, anyone who has AVR programmer can repeat this device.

As promised in the beginning of this article .

And finally - "Yes arrive with you strength."

Source: