header
// 1-Principles and proyect management   // 2-Computer-aided design // 3-computer-controlled cutting
// 4-electronics production // 5-3D scanning and printing // 6-electronics design // 7-molding and casting
// 8-embedded programming // 9-computer-controlled machining // 10-input devices // 11-composites  
// 12-interface & application programming // 13-output devices // 14-networking & communications
// 15-mechanical design, machine design // 16-appplications and implications
// 17-invention, intellectual property and income // 18-project development
// FinalProject // 

Week13: Output devices

The goal for this week is to build and program a pcb that do something with an output piece, like video, leds, speaker or something like that...lets start!


The Attiny45



The microcontroller for this output devices are the Attiny45, wich we used 2 weeks ago in "Input Devices". Here is the resume ot the Attiny45:

resume of the datasheet Attiny45


Building the Hello Speaker board


The Roland modela is enough know for me, so i had no trouble in milling the pcb. Normal parameters in the milling process, as you can see in the Week4.

Download the traces

Download the interior

So now we had all the components to build the hello.speaker.45:

components to bouild hello.speaker.45


After soldering all the components to the pcb we had this nice pcb:

hello.speaker soldered

Well, my skill in soldering is getting better day after day, but i still need to improve :)

PROBLEM: I had some confusion in distinguish the MOSFET N and the IC2 regulator. Both have three pins , two in one side and other in the other side. Our instructor says that the 5v regulator was the one with the "LOB" letters over it. So, the other one is the MOSFET :)

Connecting the power and the speaker to the pcb


Now we need a speaker to connect to the pcb. Initially I used the speaker GC0351M-ND from Digikey, but after i reallize that i had some pc cases without use, where i found some pc speakers. After use one and other, the pc speaker has more power and a clear sound than the one from digikey.


Here is the digikey speaker:

digikey speaker GC0351M-ND

And here is my pc speaker, with cable included. I just have to change the GND FASTON connect to put it beside the VCC:


pc speaker to use with hello.speaker.45


PROBLEM: The J3 jumper, where the speaker is connected, after some plugin and unplugin the speaker, finally fall down. So i decidet to attach some wire to the pin 1 and 3, GND and VCC, and then solder this wires to the speaker cable:


soldering wires to connect speaker

I still dont know the utility of the pin 2 and 4 in the speaker jumper, it works without use it :/


Programming the hello.speaker


Now lets program the pcb. Here are the connections to program the board with my FabISP. I need to power the board, so i use a 9v battery attached to the pcb at the J2 jumper. The GND is at the edge of the pcb, and VCC is the other.


programming the hello.speaker

After attaching all the connections, we need to flash the board. We need to download the files to program it:


Download C program

Download makefile

Download ASM file (for the second part)


In Ubuntu, all we had to do to program the board is open a terminal, go to the folder where we download this files and type:


$ sudo make -f hello.speaker.45.make program-usbtiny


After this, the board must start playing sounds like this:


Using ASM files to program the board

source of knowledge to build a ASM: see this link


Aditionally we have an ASM file, wich has some wave sound to play in our board. To program our hello.speaker with this sounds, we need to compile this .asm file into a .hex file. To do this we have a nice and small program to do this: "GAVRASM"

This small program (you can use in Linux, Windows and MAC) compile a assembler file (.asm) into an hexadecimal file (.hex), which we can use to program the board. So we download the program and put in a folder.


In Ubuntu we must be placed in the folder where the program is (gavrasm file), and execute the comand over th .asm file, where ever we have it. The easy way is to copy the program in the same folder where we have the .asm file we download before, and type:


$ sudo gavrasm hello.speaker.45.wave.asm


And we have an output like this:


+------------------------------------------------------------+
| gavrasm gerd's AVR assembler Version 2.1 (C)2006 by DG4FAC |
+------------------------------------------------------------+
Compiling Source file: hello.speaker.45.wave.asm
-------
Pass: 1
Line: 13
Warning 009: Include defs not necessary, using internal values!
File: hello.speaker.45.wave.asm, Line: 13
Source line: .include "tn45def.inc"
131 lines done.

Pass 1 ok.
-------
Pass: 2
Line: 13
Warning 009: Include defs not necessary, using internal values!
File: hello.speaker.45.wave.asm, Line: 13
Source line: .include "tn45def.inc"
Line: 54
Warning 004: Number of bytes on line is odd, added 00 to fit program memory!
File: hello.speaker.45.wave.asm, Line: 54
Source line: .db 18,5,250,5,250,5,250,5,250,5,250,5,250,10,250,10,250,10,250,20,250,20,250,20,250,15,250,30,200,40,100,35,100,35,100,25,200
131 lines done.

Warning 001: 1 symbol(s) defined, but not used!


47 words code, 69 words constants, total=116 = 5.7%

3 warnings!
Compilation completed, no errors. Bye, bye ...
blairevans@ubuntu:~/Desktop/PCB_projects/speaker$ avrdude -c usbtiny -p t45 -U flash:w:hello.speaker.45.wave.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9206
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "hello.speaker.45.wave.hex"
avrdude: input file hello.speaker.45.wave.hex auto detected as Intel Hex
avrdude: writing flash (232 bytes):

Writing | ################################################## | 100% 0.53s



avrdude: 232 bytes of flash written
avrdude: verifying flash memory against hello.speaker.45.wave.hex:
avrdude: load data flash data from input file hello.speaker.45.wave.hex:
avrdude: input file hello.speaker.45.wave.hex auto detected as Intel Hex
avrdude: input file hello.speaker.45.wave.hex contains 232 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.34s



avrdude: verifying ...
avrdude: 232 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done. Thank you.

Now we had a new .hex file with the same name than the original, so we have a hello.speaker.wave.hex file.

Lets put this .hex file into the attiny45:

$ avrdude -c usbtiny -p t45 -U flash:w:hello.speaker.45.wave.hex


And now we have this sweet melody on out attiny45:



PROGRAMMING WITH ARDUINO


Well, i want to have the control of the notes. I study the C file of Neil (which have a random serial of notes instead a melody) and the HEX file (wich has a melody, but nothing comprensible to me inside). If you are curious about programming pc speaker with C, should follow this link.

So i investigate in internet about controlling a pc speaker with Arduino, and some entries in google took me where i want to go.


First of all, in the LillyPad proyect i could find the code to use with my board. Just have to change the pin of the speaker (in hello.speaker, the speaker is in the Pin 1 of arduino) and the rest of the code is perfect. Also had to change the seconds to each note, from 500 to 50. (In this code 100 are about 1 sec.)


The original file only comes with the notes in the 7th Octave, but thanks to this great page (must see, also explains really well the HIGH bit and LOW bit) i could get the frecuency of all the notes in all the octaves. Inside my code you could find this table, and also the code for the 6th octave notes.

After having the code, just have to put it in the board. Remember you must select a Attiny45 (8Mhz) from the hardware list, and the USBTiny programmer in the programmer list.

Download the code

See a video with the result:




Here is the code of the song played by my board:


/*

 * LilyPad tutorial: sound

 *

 * Uses a LilyPad speaker module to produce simple musical notes

 * For a chart of the frequencies of different notes see:

 * http://www.phy.mtu.edu/~suits/notefreqs.html

 */

 

int ledPin = 13;     // LED is connected to digital pin 13

int speakerPin = 1;     // speaker connected to digital pin 9

       

void setup()      

{      

         pinMode(ledPin, OUTPUT);     // sets the ledPin to be an output. IN THIS CASE THERE ISNT LED

         pinMode(speakerPin, OUTPUT);     // sets the speakerPin to be an output

}      

       

void loop()     // run over and over again

{      

          scale();     // call the scale() function

          delay(1000);     // delay for 1 second

}      

       

void beep (unsigned char speakerPin, int frequencyInHertz, long timeInMilliseconds)     // the sound producing function

{      

          int x;      

          long delayAmount = (long)(1000000/frequencyInHertz);

          long loopTime = (long)((timeInMilliseconds*1000)/(delayAmount*2));

          for (x=0;x<loopTime;x++)      

          {      

              digitalWrite(speakerPin,HIGH);

              delayMicroseconds(delayAmount);

              digitalWrite(speakerPin,LOW);

              delayMicroseconds(delayAmount);

          }      

}      

       

void scale ()

{      

          

       

        /*  NOW JUST SHOWING THE NOTES AND FRECUENCIES. GO DOWN FOR THE WORKING CODE

        Do=C

        Re=D

        Mi=E

        Fa=F

        Sol=G

        La=A

        Si=B


        TABLE  OF MUSICAL NOTE FREQUENCIES (Hz)


             Octave 0    1    2    3    4    5    6    7

    Note

     C              16   33   65  131  262  523 1046 2093

     C#             17   35   69  139  277  554 1109 2217

     D              18   37   73  147  294  587 1175 2349

     D#             19   39   78  155  311  622 1244 2489

     E              21   41   82  165  330  659 1328 2637

     F              22   44   87  175  349  698 1397 2794

     F#             23   46   92  185  370  740 1480 2960

     G              24   49   98  196  392  784 1568 3136

     G#             26   52  104  208  415  831 1661 3322

     A              27   55  110  220  440  880 1760 3520

     A#             29   58  116  233  466  932 1865 3729

     B              31   62  123  245  494  988 1975 3951

       

          OCTAVE 6

          beep(speakerPin,1046,500);     //C6: play the note C (C7 from the table above) for 5s

          beep(speakerPin,1109,500);     //C6#

          beep(speakerPin,1175,500);     //D6

          beep(speakerPin,1244,500);     //D6#

          beep(speakerPin,1328,500);     //E6

          beep(speakerPin,1397,500);     //F6

          beep(speakerPin,1480,500);     //F6#

          beep(speakerPin,1568,500);     //G6

          beep(speakerPin,1661,500);     //G6#

          beep(speakerPin,1760,500);     //A6

          beep(speakerPin,1865,500);     //A6#

          beep(speakerPin,1975,500);     //B6

         

          OCTAVE 7

          beep(speakerPin,2093,500);     //C7: play the note C (C7 from the chart linked to above) for 5s

          beep(speakerPin,2217,500);     //C7#

          beep(speakerPin,2349,500);     //D7

          beep(speakerPin,2489,500);     //D7#

          beep(speakerPin,2637,500);     //E7

          beep(speakerPin,2793,500);     //F7

          beep(speakerPin,2960,500);     //F7#

          beep(speakerPin,3136,500);     //G7

          beep(speakerPin,3322,500);     //G7#

          beep(speakerPin,3520,500);     //A7

          beep(speakerPin,3729,500);     //A7#

          beep(speakerPin,3951,500);     //B7

          beep(speakerPin,4186,500);     //C7  FINISH SHOWING THE NOTES*/

         

//STARTING THE WORKING CODE

        digitalWrite(ledPin,HIGH);     //turn on the LED

          delay(100);

         

          beep(speakerPin,1568,40);     //G

          delay(10);

          beep(speakerPin,1568,40);     //G

          delay(10);

          beep(speakerPin,1568,5);     //G

          delay(5);

          beep(speakerPin,1568,40);     //G

          delay(20);

          beep(speakerPin,1244,40);     //D#

          delay(5);

          beep(speakerPin,1865,5);     //A#

          delay(5);

          beep(speakerPin,1568,40);     //G

          delay(20);

          beep(speakerPin,1244,40);     //D#

          delay(10);

          beep(speakerPin,1865,5);     //A#

          delay(5);

          beep(speakerPin,1568,70);     //G

         

          delay(50);

         

          beep(speakerPin,2349,40);     //D

          delay(10);

          beep(speakerPin,2349,40);     //D

          delay(10);

          beep(speakerPin,2349,5);     //D

          delay(5);

          beep(speakerPin,2349,40);     //D

          delay(20);

          beep(speakerPin,2489,40);     //D#

          delay(5);

          beep(speakerPin,1865,5);     //A#

          delay(5);

          beep(speakerPin,1480,40);     //F#

          delay(20);

          beep(speakerPin,1244,40);     //D#

          delay(10);

          beep(speakerPin,1865,5);     //A#

          delay(5);

          beep(speakerPin,1568,70);     //G

         

          delay(50);

         

         

          beep(speakerPin,3322,40);     //G#

          delay(10);

          beep(speakerPin,1661,40);     //G#

          delay(10);

          beep(speakerPin,1661,5);     //G#

          delay(5);

          beep(speakerPin,3322,40);     //G#

          delay(20);

          beep(speakerPin,2960,40);     //F7#

          delay(10);

          beep(speakerPin,2793,15);     //F

          delay(5);

          beep(speakerPin,2637,10);     //E

          delay(5);

          beep(speakerPin,2489,10);     //D#

          delay(5);

          beep(speakerPin,2637,10);     //E

         

         

         

          delay(80);

         

          beep(speakerPin,1661,10);     //G#

          delay(5);

          beep(speakerPin,2217,40);     //C#

          delay(20);

          beep(speakerPin,2093,40);     //C

          delay(10);

          beep(speakerPin,1975,15);     //B

          delay(5);

          beep(speakerPin,1865,10);     //A#

          delay(5);

          beep(speakerPin,1760,10);     //A

          delay(5);

          beep(speakerPin,1865,10);     //A#

         

          delay(80);

//repeat

         

          beep(speakerPin,1244,10);     //D#

          delay(5);

          beep(speakerPin,1480,60);     //F#

          delay(10);

          beep(speakerPin,1244,40);     //D#

          delay(10);

          beep(speakerPin,1480,10);     //F#

          delay(5);

          beep(speakerPin,1865,60);     //A#

          delay(10);

          beep(speakerPin,1568,40);     //G6

          delay(10);

          beep(speakerPin,1865,10);     //A6#

          delay(5);

          beep(speakerPin,2349,80);     //D7

         

         

          delay(80);

         

             beep(speakerPin,3322,40);     //G#

          delay(10);

          beep(speakerPin,1661,40);     //G#

          delay(10);

          beep(speakerPin,1661,5);     //G#

          delay(5);

          beep(speakerPin,3322,40);     //G#

          delay(20);

          beep(speakerPin,2960,40);     //F7#

          delay(10);

          beep(speakerPin,2793,15);     //F

          delay(5);

          beep(speakerPin,2637,10);     //E

          delay(5);

          beep(speakerPin,2489,10);     //D#

          delay(5);

          beep(speakerPin,2637,10);     //E

         

         

         

          delay(80);

         

          beep(speakerPin,1661,10);     //G#

          delay(5);

          beep(speakerPin,2217,40);     //C#

          delay(20);

          beep(speakerPin,2093,40);     //C

          delay(10);

          beep(speakerPin,1975,15);     //B

          delay(5);

          beep(speakerPin,1865,10);     //A#

          delay(5);

          beep(speakerPin,1760,10);     //A

          delay(5);

          beep(speakerPin,1865,10);     //A#

         

          delay(80);

         

         

         

          beep(speakerPin,1244,10);     //D#

          delay(5);

          beep(speakerPin,1480,40);     //F#

          delay(20);

          beep(speakerPin,1244,40);     //D#

          delay(10);

          beep(speakerPin,1865,15);     //A6#

          delay(5);

          beep(speakerPin,1568,80);     //G6

          delay(15);

          beep(speakerPin,1244,60);     //D#

          delay(5);

          beep(speakerPin,1865,25);     //A6#

          delay(5);

          beep(speakerPin,1568,200);     //G6

         

         

          digitalWrite(ledPin,LOW);     //turn off the LED

}      






This video help me to see the notes to play the music :)