3 Simple Ways to
Share What You Make

With Instructables you can share what you make with the world — and tap into an ever-growing community of creative experts.

PhotosPhotos

Share one or more photos of a project, recipe, or whatever you've made, quickly and easily.

Step by StepStep-By-Step

Share your step-by-step photos with text instructions of what you made so others can do it too!

VideoVideo

Share your how-to video. You'll need your embed code from a video site such as YouTube.

Microcontroller Fabric Tone Generator in C-code

Step 8Code

Code
If you have never programmed a chip before, this is a somewhat daunting task. It doesn't help that the tools are flaky and most of the time you have to perform the same operation multiple times. The two best resources I've found for getting an understanding of what's going on is the page for the USBtinyISP, http://www.ladyada.net/make/usbtinyisp/ and the crash course in programming the noise toy, http://blog.makezine.com/archive/2008/05/noise_toy_crashcourse_in.html These should be able to get you started.

A lot of people like Arduino for this coding and there's nothing wrong with using it, except I feel it adds a lot of bloat to a normally simple program. Also, I knew C and don't know Arduino. Maybe one day, if there's time. :)

Code:
{{{
#include <avr/io.h>
//Use a pin to turn on the SPK

/// Typedefs //////////
typedef unsigned char u8;

int main(void)
{
    u8 btnState0;
    u8 btnState1;
    u8 btnState2;
    u8 btnState3;
    u8 btnState4;
    u8 btnState5;
    u8 btnState6;

    DDRB = (1 << DDB6); //Set SPK for output
    PORTD =(1 << PD0) | (1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4); //Set Button High
    PORTC = (1 << PC4) | (1 << PC6);
    TCCR2B = (1 << CS21); //Set Up Timer
   
    while (1)
    {
        btnState0 = ~PINC & (1 << PC5);
        btnState1 = ~PINC & (1 << PC4);
        btnState2 = ~PIND & (1 << PD0);
        btnState3 = ~PIND & (1 << PD1);
        btnState4 = ~PIND & (1 << PD2);
        btnState5 = ~PIND & (1 << PD3);
        btnState6 = ~PIND & (1 << PD4);
       
        if (btnState0)
        {
            if (TCNT2 >= 190)
            {
                PORTB ^= (1 << PD6); //Flip SPK Pin
                TCNT2 = 0;
            }
        }
        if (btnState1)
        {
            if (TCNT2 >= 179)
            {
                PORTB ^= (1 << PD6); //Flip SPK Pin
                TCNT2 = 0;
            }
        }
        if (btnState2)
        {
            if (TCNT2 >= 159)
            {
                PORTB ^= (1 << PD6); //Flip SPK Pin
                TCNT2 = 0;
            }
        }
        if (btnState3)
        {
            if (TCNT2 >= 142)
            {
                PORTB ^= (1 << PD6); //Flip SPK Pin
                TCNT2 = 0;
            }
        }
        if (btnState4)
        {
            if (TCNT2 >= 126)
            {
                PORTB ^= (1 << PD6); //Flip SPK Pin
                TCNT2 = 0;
            }
        }
        if (btnState5)
        {
            if (TCNT2 >= 119)
            {
                PORTB ^= (1 << PD6); //Flip SPK Pin
                TCNT2 = 0;
            }
        }
        if (btnState6)
        {
            if (TCNT2 >= 106)
            {
                PORTB ^= (1 << PD6); //Flip SPK Pin
                TCNT2 = 0;
            }
        }
    }
}

}}}
Where do the pitches come from? A little math was needed. The timer clock on the atmega 168 runs at 1MHz. That's much too fast for audio so we have to use the prescaler /8. Then since we need to flip the output pin high then low in order to make 1 cycle, we need to divide the answer by 2 in order to come up with the right pitch. The formula looks like this,
Pitch to put in code= (1000000/8)/(Target frequency*2)
For A(440) this would be 125000/880=142.045 or 142 for our purposes, since the value must be an integer.
The target frequencies of notes can be found just about anywhere online and are generally all the same.

I still want to add a case statement instead of using a bunch of Ifs and use PWM to better control the volume and pitch of the speaker, but for now, this works.
« Previous StepDownload PDFView All StepsNext Step »

Pro

Get More Out of Instructables

Already have an Account?

close

All Steps Viewing
View all steps of an Instructable on the same page when you're a Pro Member.

Upgrade to Pro today!
9
Followers
7
Author:pstretz