Working with microcontroller-generated audio frequencies (adapted from the Machine Science tutorial)



Similar documents
Your Multimeter. The Arduino Uno 10/1/2012. Using Your Arduino, Breadboard and Multimeter. EAS 199A Fall Work in teams of two!

Ultrasonic Distance Measurement Module

1602 LCD adopts standard 14 pins(no backlight) or 16pins(with backlight) interface, Instruction of each pin interface is as follows:

Eric Mitchell April 2, 2012 Application Note: Control of a 180 Servo Motor with Arduino UNO Development Board

DEPARTMENT OF ELECTRONICS ENGINEERING

PHYS 2P32 Project: MIDI for Arduino/ 8 Note Keyboard

Basic Pulse Width Modulation

Arduino Lesson 14. Servo Motors

Trigonometric functions and sound

LAB4: Audio Synthesizer

ARRL Morse Code Oscillator, How It Works By: Mark Spencer, WA8SME

What you will do. Build a 3-band equalizer. Connect to a music source (mp3 player) Low pass filter High pass filter Band pass filter

H-Bridge Motor Control

CHAPTER 11: Flip Flops

Controlling a Dot Matrix LED Display with a Microcontroller

Student Exploration: Circuits

IR Communication a learn.sparkfun.com tutorial

MP3 Player. Add an MP3 module to the board and design a user interface. Overview Challenge 1: Control the MP3 Module with Your Computer

Pulse Width Modulation Applications

L201+ L53 L201+ L L201+ L53 L201+ L53 L201+ L53 L201+ L53 L201+ L201+ L201+ L53. * <

Arduino project. Arduino board. Serial transmission

Arduino Microcontroller Guide W. Durfee, University of Minnesota ver. oct-2011 Available on-line at

Pulse width modulation

Interfacing Analog to Digital Data Converters

Arduino Shield Manual

Measurement of Capacitance

Rectifier circuits & DC power supplies

Analog and Digital Signals, Time and Frequency Representation of Signals

- 35mA Standby, mA Speaking pre-defined phrases with up to 1925 total characters.

Voltage. Oscillator. Voltage. Oscillator

Accurate Measurement of the Mains Electricity Frequency

Lab 6 Introduction to Serial and Wireless Communication

Bluetooth + USB 16 Servo Controller [RKI-1005 & RKI-1205]

Using Arduino Microcontrollers to Sense DC Motor Speed and Position

How To Control A Car With A Thermostat

[F/T] [5] [KHz] [AMP] [3] [V] 4 ) To set DC offset to -2.5V press the following keys [OFS] [+/-] [2] [.] [5] [V]

GT Sensors Precision Gear Tooth and Encoder Sensors

Display Board Pulse Width Modulation (PWM) Power/Speed Controller Module

Start A New Project with Keil Microcontroller Development Kit Version 5 and Freescale FRDM-KL25Z

Cello_Titan. A piece for electric cello and maxmsp Or a piece for Ulrich Maiß. Written by KTToeplitz. In 2005 Duration is around 8-10 minutes

21. PID controller SYSTEM ACTUATOR. Figure 1: A crude example for a regulation

Microcontroller Systems. ELET 3232 Topic 8: Slot Machine Example

COMS 4115 Programming Languages and Translators Fall 2013 Professor Edwards. Lullabyte

Creating a Project with PSoC Designer

Special Lecture. Basic Stamp 2 Programming. (Presented on popular demand)

1. Learn about the 555 timer integrated circuit and applications 2. Apply the 555 timer to build an infrared (IR) transmitter and receiver

After: bmotorreflected[port2]= 1; //Flip port2 s direction

BXR 300C BXR 300R. Owner, s Manual P/N

APPLICATION NOTES: Dimming InGaN LED

Small Hardware Development and Prototyping Board for the SX28

Bluetooth Portable Boombox

Arduino Lesson 4. Eight LEDs and a Shift Register

Measuring Resistance Using Digital I/O

Constructing a precision SWR meter and antenna analyzer. Mike Brink HNF, Design Technologist.

Arduino Lesson 9. Sensing Light

Programming PIC Microcontrollers in PicBasic Pro Lesson 1 Cornerstone Electronics Technology and Robotics II

AXE033 SERIAL/I2C LCD

Arduino DUE + DAC MCP4922 (SPI)

IEC ESD Immunity and Transient Current Capability for the SP72X Series Protection Arrays

Introduction to Arduino

Advanced Programming with LEGO NXT MindStorms

Character LCDs. Created by Ladyada. Last updated on :45:29 PM EDT

Servo Motor API nxt_motor_get_count nxt_motor_set_count nxt_motor_set_speed

Lab E1: Introduction to Circuits

Renaissance Bass. software audio processor. User s Guide

Connecting Arduino to Processing a

E-Blocks Easy Internet Bundle

Introduction to Arduino

Arduino Lesson 1. Blink

MoTeC USA GPS. Part # M GPS BL Available in 10 Hz or 20 Hz. USER MANUAL Version 1.4

UNBALANCED OUTPUT TO BALANCED INPUT WIRING METHODS

The Operational Amplfier Lab Guide

FREQUENCY RESPONSE OF AN AUDIO AMPLIFIER

Impedance Matching and Matching Networks. Valentin Todorow, December, 2009

UNDERSTANDING AND CONTROLLING COMMON-MODE EMISSIONS IN HIGH-POWER ELECTRONICS

MAGICAR M871A. Car alarm with two-way remote User s guide

4/Really Getting Started with Arduino

Mach3 Tutorial Setting up a basic three axis milling machine. Based on Mach3 2.0

AN2680 Application note

PRODUCT SHEET OUT1 SPECIFICATIONS

Arduino Shield Manual

Series and Parallel Resistive Circuits

AN3998 Application note

Set up and Blink - Simulink with Arduino

Surveillance System Using Wireless Sensor Networks

2013 G Miller. 3 Axis Brushless Gimbal Controller Manual

Hands On ECG. Sean Hubber and Crystal Lu

Confidence Intervals for the Difference Between Two Means

Zeros, Ones, and the Morse Code

Microprocessor Home Security System

AN601 I2C 2.8 Communication Protocol. SM130 SM130 - Mini APPLICATION NOTE

Data Transmission Using Laser Light

Arduino Lab 1 - The Voltage Divider

OPERATING MANUAL. Table of contents. 2 Phase Stepping Motor Driver 2M542. Rev. A. Introduction page 2. Specifications page 2 Timing chart page 3

Inductive Sensors Single or Dual Loop Detectors Type LD with teach-in

Exercises for Design of Test Cases

Transcription:

Working with microcontroller-generated audio frequencies (adapted from the Machine Science tutorial) If we attach a speaker between a microcontroller output pin and ground, we can click the speaker in the same way we blink an LED. When the pin goes high (5 volts at the output) the current creates an electromagnetic field that causes the speaker to flex. When the pin goes low (zero volts at the output) the speaker contracts back to its previous position. Constantly flexing the speaker back and forth at the right speed will generate an audible tone. The process of the pin going high for a duration and then going low for a duration is called a cycle, and the total high-pin duration plus the low-pin duration is referred to as the period of the frequency. Frequency can be calculated two different ways: frequency = 1 / period -orfrequency = cycles / second Both equations produce the same result. Consider the example shown in the figure below: frequency = 1 / period frequency = 1 / (0.5 seconds) frequency = 2 cycles / second -orfrequency = cycles / second frequency = (3 cycles) / (1.5 seconds) frequency = 2 cycles / second The most common unit of frequency is the Hertz. One cycle per second is equal to one Hertz. 1 Hertz = 1 cycle / second Therefore, in the example shown above, the frequency is 2 Hertz. Now that you know how frequency and period are related, it is possible to determine the frequency of the tone your speaker will produce, just by looking at your code. The period of the tone will be the sum of the two delays in each cycle of your for... loop. Using the Machine Science compiler, we can make use of two delay functions: delay_ms(); -delay in milliseconds and delay_us(); -delay in microseconds (note use of letter u to stand for µ -the Greek letter Mu.) For example, in the following code, the delays are 1,000 microseconds each: delaymicroseconds(1000); <------------ a 1000-microsecond delay delaymicroseconds(1000); <------------ a 1000-microsecond delay Therefore, to calculate frequency: frequency = 1 / (1000 microseconds + 1000 microseconds) frequency = 1 / (2000 microseconds) frequency = 1 / (0.002 seconds) frequency = 500 hertz

Playing Specific Frequencies By adjusting the delays in your for... loop, you can program the microcontroller to produce a tone with a specific frequency--in other words, a musical note. The table below shows seven musical notes, together with their frequencies. The note A has a frequency of 440 cycles per second; the note B has a frequency of 494 cycles per second; and so on. Let's start with the following code: //--- "Speaker_Start" Plays a pitch thru a speaker and lights an LED --- //--- Set up: > Attach a piezo speaker between ground and Digital pin 8 // > Wire an LED from Digital pin 7 thru a 330 ohm resistor to gnd #include "machinescience.h" // included software libraries to use #include "lcd.h" void setup() { // Only do once at startup pinmode(8, OUTPUT); // Define Speaker pin pinmode(6, OUTPUT); // Define LED pin lcd_init(); // initialize lcd screen // repeat forever lcd_clear(); lcd_instruction(goto_line1); lcd_text("beep!"); // Print message to LCD screen digitalwrite(6, HIGH); // Turn on LED for(i = 0; i < 300; i++) // number of vibrations (duration) { digitalwrite(8, HIGH); // speaker Pin high delaymicroseconds(1500); // delay before releasing speaker digitalwrite(8, LOW); // speaker Pin low delaymicroseconds(1500); // end loop for one pitch digitalwrite(6, LOW); // Turn off LED lcd_clear(); lcd_text("quiet."); // Print message to LCD screen delay(1000); // wait 1 sec (1000 milliseconds) The delays in the above code use an integer of 1500 in the delay statement to generate delays of 1500 millionths of a second. Now, if we wanted to figure out how long the delays in our on/off states (pulses) should be to produce a specific pitch (note), how would we calculate that?

Calculating Pulse Length from Frequency Let's use note A (440 hz) as an example. It's accomplished in two steps: 1. period = 1000000 / frequency Each period (cycle, in hertz) is the length of one second divided by the frequency. We are using a delay measurement is in microseconds ( delay_us(); ) so a duration of one second is one million microseconds (1000000). Therefore our period will be 1000000 / 440, or 2272.7272. once we know the total period of one cycle is 2272.7272 millionths of a second, the last part is easy. The delay for each pulse-on and pulse-off is half of that. 2. pulse = period / 2 2272.7272 divided by 2 is approximately 1136.3636. So the code in our main loop to generate a frequency of A-440 for a duration of 200 clicks would be: for(i = 0; i < 200; i++) // For 200 times (duration) { digitalwrite(6, HIGH); // speaker Pin high delaymicroseconds(1136); // delay before releasing speaker digitalwrite(6, LOW); // speaker Pin low delaymicroseconds(1136); // end loop for one pitch Using a custom function Let's improve on the previous program with a version that does this math for us in a separate function so our main loop can just play a pitch without having to deal with switching pins high and low. Let's also use variables of type long when we need to do floating point calculations. //------------------- a168_speaker_w_function.c --------------------- // > Wire an LED from D7 (pin 13) thru a 330 ohm resistor to gnd //---- Here we define a function called play_pitch -------- void play_pitch(int freq){ // Define a function called play_pitch period pulse period = 1000000/freq; // Calculate period pulse = (period / 2 ); // Calculate pulse for(i = 0; i < 200; i++){ // Loop 200 times (duration) // end loop // end function definition //---- Having defined it, now we can use it in our main loop that follows: void setup(){ pinmode(6, OUTPUT); // Define Speaker pin pinmode(7, OUTPUT); // Define LED pin

void loop (){ play_pitch(440); // Turn on LED // Run the function we defined above // Turn off LED Adding duration calculation to our custom function: So far, every time we have played a pitch we've done so by clicking the speaker 200 times. The number of time we click the speaker determines the duration of the pitch. This presents a problem if we want to play a melody with each note being the same duration -because click 200 high frequency pulses takes a shorter amount of time than clicking 200 low frequency pulses. We can solve this by including in our function a calculation of duration as well, so the number of times the speaker clicks changes based on the frequency. We'll use a variable called cycles in an equation written so that higher frequencies have more speaker clicks. The algorithm has three parts: 1. We make the following calculations: period = 1000000 / freq; pulse = period / 2; 2. We use the variable cycles in our For Loop (instead of a hard-coded value like 200) for(i=0; i<=cycles; i++) 3. In our main loop, when we call our play_pitch() function, we pass along frequency and duration: play_pitch(440, 100); So putting that together, we can make the following program: //------------------- speaker_freq_dur.c --------------------- // > Wire an LED from D7 (pin 13) thru a 330 ohm resistor to gnd //---- Here we define a function called play_pitch void play_pitch(int freq, int duration){ long cycles; // variable for number of cycles (duration) period = 1000000/freq; //Calculate period pulse = (period / 2 ); //Calculate pulse for(i = 0; i < cycles; i++){ // Loop for number of cycles // end loop // end function definition //---- Having defined it, now we can use it in the program that follows void setup(){ pinmode(6, OUTPUT); // Define Speaker pin pinmode(7, OUTPUT); // Define LED pin

play_pitch(587, 200); play_pitch(659, 400); // Turn on LED // Run function with frequency & duration // Turn off LED Now if you initialized variable names like: int A = 440; or int longnote=800; or int shortnote=100; it would be possible to write statements like: play_pitch(a, shortnote); Try different variations. Here's a version that generates random pitches in an infinite loop: //------------------- speaker_random_freq.c --------------------- //---- Here we define a function called play_pitch void play_pitch(int freq, int duration){ long cycles; // variable for number of cycles (duration) period = 1000000/freq; //Calculate period pulse = (period / 2 ); //Calculate pulse for(i = 0; i < cycles; i++){ // Loop for number of cycles // end loop // end function definition //---- Having defined it, now we can use it in our main loop that follows void setup (){ int r_freq; srand((int)15); //Set "seed" for random number generator pinmode(6, OUTPUT); // Define Speaker pin r_freq = rand(); // Grab a random number, store it in "freq" r_freq = r_freq/30; // scale freq by some amount play_pitch(r_freq, 150); // Run function with frequency & duration