Lab5 - Super Mario Coin Bank
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
(1 vote)
- Login to post comments
Drupal theme by Kiwi Themes.