Skip to main content

Day 7: Random Numbers and Recursion | Sound

Lecture

Random Numbers

Random numbers can be generated using the rand function, however, the same value would be printed since it generates integers in a specified sequence. To generate a new sequence of random numbers each time, a new random-number seed is needed. First, I need to use srand to generate a seed in order for the rand function to generate new random numbers every time.

We can also generate random integers between specified limits. 

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  /* Declare variables and function prototype. */
  unsigned int seed;
  int a, b, k;
  int rand_int(int a,int b);
  /* Get seed value and interval limits. */
  printf("Enter a positive integer seed value: \n");
  scanf("%u",&seed);
  srand(seed);
  printf("Enter integer limits a and b (a<b): \n");
  scanf("%i %i",&a,&b);
  /* Generate and print ten random numbers. */
  printf("Random Numbers: \n");
  for (k=1; k<=10; k++)
  printf("%i ",rand_int(a,b));
  printf("\n");
  /* Exit program. */
  return 0;

}

int rand_int(int a,int b)
{
  return rand()%(b-a+1) + a;
}

Recursion

Recursive functions are functions that call themselves. The problem is continually redefined until some limit is reached. 
One example is the factorial computation.


//Recursive factorial
//This function calculates the factorial for a user-given integer
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(void)
{
  int n;
  //Declare function prototype
  long factorial_r(double k);
  //Ask for user to input integer
  printf("Enter positive integer: \n");
  scanf("%i",&n);
  //Print values
  printf("Recursive: %i!= %ld \n",n,factorial_r(n));
  return 0;
}

//Recursive factorial function
long factorial_r(double k)
{
  //Function will continue until k reaches 0
  if(k==0)
  {
    return 1;
  }
  else
  {
    return k*factorial_r(k-1);
  }
}

Lab

How the Arduino Makes Sound

Sound is a pressure wave, and is created by an object when the object vibrates, which causes the air around it to vibrate. The vibrating air transfers energy to particles around them, and sound is perceived when a pressure wave is transferred from the source to the eardrum.

The Arduino can control the frequency and amplitude of a sound wave. The frequency affects the pitch, with high frequencies being higher-pitched and low frequencies being low-pitched. Amplitude affects volume, with higher amplitudes being louder and lower amplitudes being quieter.

The Arduino does not make sinusoidal waves, but instead produces square waves, which "jump" from high to low values rather than oscillating smoothly like a sinusoidal wave. The amplitude is adjusted by altering the amount of current flowing through the speaker. 

Speakers utilize electromagnetic forces to turn electricity into motion. A magnet on a speaker is mounted behind a voice coil and pole piece. As a wave voltage signal is sent into the leads of the coil, the pole piece and diaphragm vibrate up and down as the magnet is attracted to and then repulsed by the magnetic field induced by the changing current. This vibration then creates sound by vibrating the air around it. 

Making Sounds on the Arduino

Functions

tone(pin,frequency,duration)
 noTone(pin)

The tone function generates a square wave of a selected frequency on one's choice of pin.
noTone stops the tone.

Wiring

Some notes:

  • I/O pins can supply max 40 mA, resistor should be selected to prevent exceeding max
  • Speaker has internal resistance 8ê­¥
  • R=V/I   5V/40mA = 125ê­¥. Subtracting 8ê­¥ from this is 117ê­¥. Closest common resistor is 150ê­¥

Programming

I created a custom header file called pitches.h, which contains the values of each note from B0 to D-sharp 8. This makes it easier to call notes later. 

#define b0  31
#define c1  33
#define cs1 35
#define d1  37
#define ds1 39
#define e1  41
#define f1  44
#define fs1 46
#define g1  49
#define gs1 52
#define a1  55
#define as1 58
#define b1  62
#define c2  65
#define cs2 69
#define d2  73
#define ds2 78
#define e2  82
#define f2  87
#define fs2 93
#define g2  98
#define gs2 104
#define a2  110
#define as2 117
#define b2  123
#define c3  131
#define cs3 139
#define d3  147
#define ds3 156
#define e3  165
#define f3  175
#define fs3 185
#define g3  196
#define gs3 208
#define a3  220
#define as3 233
#define b3  247
#define c4  262
#define cs4 277
#define d4  294
#define ds4 311
#define e4  330
#define f4  349
#define fs4 370
#define g4  392
#define gs4 415
#define a4  440
#define as4 466
#define b4  494
#define c5  523
#define cs5 554
#define d5  587
#define ds5 622
#define e5  659
#define f5  698
#define fs5 740
#define g5  784
#define gs5 831
#define a5  880
#define as5 932
#define b5  988
#define c6  1047
#define cs6 1109
#define d6  1175
#define ds6 1245
#define e6  1319
#define f6  1397
#define fs6 1480
#define g6  1568
#define gs6 1661
#define a6  1760
#define as6 1865
#define b6  1976
#define c7  2093
#define cs7 2217
#define d7  2349
#define ds7 2489
#define e7  2637
#define f7  2794
#define fs7 2960
#define g7  3136
#define gs7 3322
#define a7  3520
#define as7 3729
#define b7  3951
#define c8  4186
#define cs8 4435
#define d8  4699
#define ds8 4978


Now in my main program I can utilize the previous custom header file to make it easier to call notes. 

//Specify Arduino pin that positive lead of speaker is attached to.
int speakerPin=9;
int thisNote=0; //Initialize variable, for use later in while loop

//Include custom header file that defines all notes and their frequencies. 
//This makes it easier to refer to notes
#include "pitches.h" 

//Input all notes in tune in an array. Because of my header file, I don't need to bother looking up frequencies for notes and can instead input the notes using scientific pitch notation
int OdetoJoy[]={
  e4,e4,f4,g4,g4,f4,e4,d4,c4,c4,d4,e4,e4,d4,d4,e4,e4,f4,g4,g4,f4,e4,d4,c4,c4,d4,e4,d4,c4,c4,d4,d4,e4,c4,d4,e4,f4,e4,c4,d4,e4,f4,e4,d4,c4,d4,g3,e4,e4,f4,g4,g4,f4,e4,d4,c4,c4,d4,e4,d4,c4,c4
  };

//Now I set all the note lengths for the tune, again in an array. I need to use doubles because I have decimals.
//The melody is in 4/4 time, therefore I give a half note 2 beats, a quarter note 1 beat, and an eighth note half a beat
double noteLength[]={
  1,1,1,1,1,1,1,1,1,1,1,1,1.5,0.5,2,1,1,1,1,1,1,1,1,1,1,1,1,1.5,0.5,2,1,1,1,1,1,0.5,0.5,1,1,1,0.5,0.5,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1.5,0.5,2
};

void setup() {
  //No setup code necessary
}

void loop() {
  //Using a while loop, I can iterate through the array of notes and note durations. It will continue to iterate until the value of thisNote is equal to the length of the array of notes
  //Note: for loop buggy. Gets stuck on low buzzing sound after one loop
  while(thisNote<=sizeof(OdetoJoy))
  {
    //I multiply the note duration by the amount of milliseconds I want the sound to play for
    double noteDuration=(520*noteLength[thisNote]);
    
    //Now I use tone to generate a tone on the speaker corresponding to the element in the array of notes (OdetoJoy)
    tone(speakerPin,OdetoJoy[thisNote]);

    //The note plays for the set duration
    delay(noteDuration);

    //I set a small period of time where no tone plays, which allows the notes to sound distinct from each other
    noTone(speakerPin);
    delay(5);
    
    thisNote++; //increment thisNote
    
    //Reset thisNote once it reaches a number greater than the size of the array of notes
    if(thisNote==63)
    {
      thisNote=0;
      noTone(speakerPin);
      delay(1000); //Longer delay to signify end
      break;
    }
  }
}

The Arduino in action! Please excuse all the random objects moving into the frame, David (yes, the SI) decided that my Arduino and breadboard needed to be surrounded by friends in the form of mundane objects lying on the table.

 

Homework


Programming Homework


Problem 1:

For problem 1, the question asks me to create a program to simulate an experiment rolling two six-sided dice, allowing the user to enter the number of rolls to simulate. 



//Two Six-Sided Dice Simulation

//This program simulates rolling two six-sided dice

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(void)
{
  unsigned int seed;
  //Function prototype
  int rand_int(int a, int b);
  int num_rolls;
  int a=1, b=6;
  
  //Allow user to enter number of dice rolls to simulate
  printf("Enter number of dice rolls to simulate\n");
  scanf("%i",&num_rolls);
  
  //Obtain seed value
  printf("Enter a positive integer seed value\n");
  scanf("%u",&seed);
  
  //Specify seed value
  srand(seed);
  printf("Numbers: \n");
  
  //Print values
  for (int k=1; k<=num_rolls;k++)
  {
    printf("Dice One: %i Dice Two: %i",rand_int(a,b),rand_int(a,b));
    printf("\n");
  }
  return 0;
}

//rand_int function 
int rand_int(int a, int b)
{
  return rand()%(b-a+1)+a;
}

Problem 2
Problem 2 asked for an integer function for computing a factorial approximation using the Stirling formula. 


//Factorial by Stirling formula

//This program computes the factorial of a number using the Stirling formula

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#define pi 3.14159265 //Set value of pi


int main(void)
{
  int n;
  //Function prototype
  int n_fact(int n);
  //Prompt user to input number to find factorial of
  printf("Input positive non-zero integer you would like to find factorial of\n");
  scanf("%i",&n);
  
  //If value is negative, factorial cannot be computed, and program exits
  if(n<=0)
  {
    printf("Value must be a positive non-zero integer\n");
    return 0;
  }
  
  //If value is positive, print the factorial
  else
  {
    printf("%i! = %li \n",n,n_fact(n));
  }
  return 0; //Exit code
}

//Function to find factorial using Stirling formula
int n_fact(int n)
{
  long factorial;
  //Stirling formula
  factorial=(sqrt(2*pi*n))*pow((n/exp(1)),n);
  return factorial;
}

Comments

Popular posts from this blog

Day 20: Structures, Programming with Pointers

Lecture Structures Structure defines set of data, but individual parts do not have to be the same type. Example 1.1 struct hurricane {  char name[10];  int year,category; }; Within a structure, variables and even arrays can be defined. Structures are also known as aggregate data types since multiple data values can be collected into a single data type. Individual values within a structure are called data members, and each member is given a name. In Example 1.1, the names of the data members are name, year, and category. To refer to a data member, the structure variable name followed by a period and a data member name is used.  Definition and Initialization Define structure. Keyword struct used to define name of structure (aka structure tag) and data members that are included in structure After structure defined, structure variables can be defined using declaration statements. Semicolon required after structure definition. Statements can appear before m...

Day 4: RGB Nightlight | Algorithm Development, Conditional Expressions, Selection Statements

Hardware: RGB Nightlight const int red=11; const int green=10; const int blue=9; const int button=4; boolean lastbutton=LOW; boolean currentbutton=LOW; int ledMode=0; void setup() {   // put your setup code here, to run once:   pinMode(button,INPUT);   pinMode(red,OUTPUT);   pinMode(green,OUTPUT);   pinMode(blue,OUTPUT); } boolean debounce(boolean last) {   boolean current=digitalRead(button);   if(last!=current)   {     delay(5);     current=digitalRead(button);   }   return current; } void setMode(int mode) {   //RED   if(mode==1)   {     digitalWrite(red,HIGH);     digitalWrite(green,LOW);     digitalWrite(blue,LOW);   }   if(mode==2)   {     //orange     digitalWrite(red,HIGH);     analogWrite(green,40);     digitalWrite(blue,LOW);...