Lab5 - Super Mario Coin Bank

Submitted by chan on Tue, 03/05/2013 - 03:20

 

Description

This Super Mario Coin Bank is a red plastic cup which makes coin sound of the Super Mario when you put a coin into it. While putting money into it, you can see the visualization of the dropping coin on a screen and automatically calculate the amount of money you put into it. This coin bank makes different sound per a dollar. The coin bank consists of 3 components: a photocell, leds, and a speaker. The photocell located below the hole detect when a coin is inserted and then, 3 LEDs will blink 3 times and a speaker makes sound. 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Components Used

1- Arduino

1- Piezo speaker

1- Photocell

1- Diffuser Glass Bottle

1-10kΩ Resistors

3- 220Ω Resistors

3- LEDs

 
 

Code

Arduino code:

/*

* Super Mario Coin Bank
* Eungchan Kim
* 2013-03-05
* Reference for speaker:
* https://code.google.com/p/rbots/source/browse/trunk/StarterKit/Lesson5_PiezoPlayMelody/Lesson5_PiezoPlayMelody.pde
*/
 
int phoPin = A0; //photocells
int ledPin[3] = {11,9,10};//RGB
int criteria = 400; // criteria for detecting if a coin is inserted
int blink_time = 3; // number of led blink times
int insert_count = 0; // count the number of inserted coins
// speaker
int speakerOut = 7;               
// period is in microsecond so P = 1/f * (1E6)
#define  g4    2551    // 392 Hz 
#define  c5    1912    // 523 Hz
#define  e5    1517
#define  g5    1276
#define  f5    1433
#define  b5    1012
#define  e6    758
#define  c6    955
#define  g6    638
#define  R     0       // Define a special note, 'R', to represent a rest
 
//super mario theme
int dollar[] = {e6, e6, R, e6, R, c6, e6, R, g6, R, R, g5};
int beats[] = {16, 16, 4, 16, 4, 16, 16, 4, 16, 4, 4, 16};
//coin sound
int q_dollar[] = {b5, e6};
int q_beats[] = {8, 40};
 
int MAX_COUNT = sizeof(dollar) / 2; // Melody length, for looping.
int MAX_COUNT4 = sizeof(q_dollar) / 2; // Melody length, for looping.
// Set overall tempo
long tempo = 10000;
// Set length of pause between notes
int pause = 1;
// Loop variable to increase Rest length
int rest_count = 50; //<-BLETCHEROUS HACK; See NOTES
// Initialize core variables
int toneM = 0;
int beat = 0;
long duration = 0;
 
void setup()
{
  Serial.begin(9600);
  pinMode(speakerOut, OUTPUT);
  for (int i=0;i<3;i++){
    pinMode(ledPin[i], OUTPUT);  // declare the ledPin as an OUTPUT
  }
}
 
void loop()
{
  int insert = analogRead(phoPin);
  if (insert < criteria){
    Serial.println(insert);
    for (int i=0;i<blink_time;i++){
      for(int i=0;i<3;i++){digitalWrite(ledPin[i],HIGH);}
      delay(100);
      for(int i=0;i<3;i++){digitalWrite(ledPin[i],LOW);}
      delay(100);
    }
    insert_count++;
 
    if (insert_count%4 ==0){
      sound(dollar,beats,MAX_COUNT);
    }
    else{
      sound(q_dollar,q_beats,MAX_COUNT4);
    }
// Set up a counter to pull from melody[] and beats[]
 
  }  
}
void sound(int* m, int* b, int max_num)
{
  for (int i=0; i<max_num; i++) {
    toneM = m[i];
    beat = b[i];
    duration = beat * tempo; // Set up timing
    playTone(); 
    // A pause between notes...
    delayMicroseconds(pause);    
  }
}
void playTone() {
  long elapsed_time = 0;
  if (toneM > 0) { // if this isn't a Rest beat, while the tone has 
    //  played less long than 'duration', pulse speaker HIGH and LOW
    while (elapsed_time < duration) {
      digitalWrite(speakerOut,HIGH);
      delayMicroseconds(toneM / 2);
      // DOWN
      digitalWrite(speakerOut, LOW);
      delayMicroseconds(toneM / 2);
      // Keep track of how long we pulsed
      elapsed_time += (toneM);
    } 
  }
  else { // Rest beat; loop times delay
    for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
      delayMicroseconds(duration);  
    }                                
  }                                 
}

 

Processing code:

/*

* Super Mario Coin Bank
* Eungchan Kim
* 2013-03-05
*
* Reference for visualization
* "Forces (Gravity and Fluid Resistence) with Vectors by Daniel Shiffman"
*/
 
import processing.serial.*;
Serial port;
 
// moving bodies
Mover[] movers = new Mover[100];
// initial setting
int num=0;
float trigger =0;
float serial_input = 0;
int draw_flag =0;
// Liquid
Liquid liquid;
 
 
void setup() {
  port = new Serial(this, "COM3", 9600);
  port.bufferUntil('\n');
  frameRate(30);
  size(800, 400);
  smooth();
  reset();
  // Create liquid object
  liquid = new Liquid(0, 0, width+10, height/5, 0.1);
}
 
void draw() {
  background(247,153,175);
  // Draw water
  liquid.display();
  for (int i = 0;i<num;i++) {
    draw_mover(movers[i]);
  } 
  if (draw_flag ==1) {
    add_mover(num); 
    if (num < 98) {
      num++;
    }
    else num =0;
    draw_flag=0;
  }
  textSize(32);
  fill(255);
  text('$',10,120);
  text(nfc(num*0.25,2), 30, 120);
  textSize(32);
  fill(247,153,175);
  text("Super Mario Piggy Bank", 10, 30);
}
void mousePressed() {
  if (num < 98) {
    num++;
  }
  else num =0;
  add_mover(num);
}
void draw_mover(Mover m) {
  // Is the Mover in the liquid?
  if (liquid.contains(m)) {
    // Calculate drag force
    PVector drag = liquid.drag(m);
    // Apply drag force to Mover
    m.applyForce(drag);
  }
  // Gravity is scaled by mass here!
  PVector gravity = new PVector(0, 0.1*m.mass);
  // Apply gravity
  m.applyForce(gravity);
  // Update and display
  m.update();
  m.display();
  m.checkEdges();
}
 
// Restart all the Mover objects randomly
void reset() {
  for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover(0, 0, 0);
  }
}
void add_mover(int i) {
  movers[i] = new Mover(random(3, 5), random(1,800), 0);
}
void serialEvent(Serial port) {
  serial_input = float(port.readStringUntil('\n'));
  draw_flag = 1;
  println(trigger);
}
/**
 * Forces (Gravity and Fluid Resistence) with Vectors 
 * by Daniel Shiffman.  
 * 
 * Demonstration of multiple force acting on bodies (Mover class)
 * Bodies experience gravity continuously
 * Bodies experience fluid resistance when in "water"
 */
 
 // Liquid class 
 class Liquid {
  // Liquid is a rectangle
  float x,y,w,h;
  // Coefficient of drag
  float c;
 
  Liquid(float x_, float y_, float w_, float h_, float c_) {
    x = x_;
    y = y_;
    w = w_;
    h = h_;
    c = c_;
  }
  
  // Is the Mover in the Liquid?
  boolean contains(Mover m) {
    PVector l = m.location;
    if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) {
      return true;
    }  
    else {
      return false;
    }
  }
  
  // Calculate drag force
  PVector drag(Mover m) {
    // Magnitude is coefficient * speed squared
    float speed = m.velocity.mag();
    float dragMagnitude = c * speed * speed;
 
    // Direction is inverse of velocity
    PVector drag = m.velocity.get();
    drag.mult(-1);
    
    // Scale according to magnitude
    drag.setMag(dragMagnitude);
    return drag;
  }
  
  void display() {
    noStroke();
    fill(255);
    rect(x,y,w,h);
  }
}
/**
 * Forces (Gravity and Fluid Resistence) with Vectors 
 * by Daniel Shiffman.  
 * 
 * Demonstration of multiple force acting on bodies (Mover class)
 * Bodies experience gravity continuously
 * Bodies experience fluid resistance when in "water"
 */
class Mover {
  // location, velocity, and acceleration 
  PVector location;
  PVector velocity;
  PVector acceleration;
  
  // Mass is tied to size
  float mass;
 
  Mover(float m, float x, float y) {
    mass = m;
    location = new PVector(x, y);
    velocity = new PVector(0, 0);
    acceleration = new PVector(0, 0);
  }
 
  // Newton's 2nd law: F = M * A
  // or A = F / M
  void applyForce(PVector force) {
    // Divide by mass 
    PVector f = PVector.div(force, mass*0.5);
    // Accumulate all forces in acceleration
    acceleration.add(f);
  }
  void update() {
    // Velocity changes according to acceleration
    velocity.add(acceleration);
    // Location changes by velocity
    location.add(velocity);
    // We must clear acceleration each frame
    acceleration.mult(0);
  }
  
  // Draw Mover
  void display() {
    stroke(177,172,49);
    strokeWeight(2);
    fill(255,248,50);
    ellipse(location.x, location.y, mass*16, mass*16);
    textSize(20);
    fill(177,172,49);
    text("$",location.x-6, location.y+7);
  }
  
  // Bounce off bottom of window
  void checkEdges() {
    if (location.y > height) {
      velocity.y *= -0.4;  // A little dampening when hitting the bottom
      location.y = height;
    }
  }
}

Demo

5
Your rating: None Average: 5 (1 vote)
Drupal theme by Kiwi Themes.