270j Final Project

From CSclasswiki
Jump to: navigation, search

CSC270 Final Project

This is an Arduino-Only project.

Goal

The goal of this project is to implement a safety fan blade whose rotational speed is dependent on the distance between an ultrasonic sensor and an object in front of it. The distance is read from the ultrasonic sensor. The smaller the distance, the slower the fan will operate; and when the distance is smaller than 10cm, the fan will stop operating.

External References

Part 1

Connect a 64-LED matrix display to my Arduino and program it to display my name "NOX".

Schematic

Wiring of a 8x8 LED matrix to Arduino Mega2650

Source Code

The following program displays the letters 'N', 'O', 'X' one at a time repeatedly.

/*  
 *  led64
 *  Nox Yu 
 *  part 1 of the final project for csc270
 *  this program makes the 8x8 LED matrix displays N, O, X, one at a time repeatedly
 */
#include <LedControl.h>

int DIN = 12;
int CS = 11;
int CLK = 10;
byte n[8] = {0xE3, 0xF3, 0xFB, 0xDD, 0xDD, 0xCF, 0xCF, 0xC7};
byte o[8] = {0x3C, 0x7E, 0xE7, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C};
byte x[8] = {0x81, 0xC3, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0xC3};
LedControl lc = LedControl(DIN, CLK, CS, 0);

// display each row on the matrix according to the bytes array input
void printByte(byte bytes[]){
  int i=0;
  for (i=0; i<8; i++ ){
    lc.setRow(0, i, bytes[i]); 
  }
}

void setup() {
  // put your setup code here, to run once:
  lc.shutdown(0, false); // shutdown the power saving mode
  lc.setIntensity(0, 15); // set brightness to max
  lc.clearDisplay(0);
}

void loop() {
  // put your main code here, to run repeatedly:
  printByte(n);
  delay(1000);
  printByte(o);
  delay(1000);
  printByte(x);
  delay(1000); 
}

Part 2

Connect an ultrasonic sensor to my Arduino. To verify that it works correctly, the 4-digit-7-segment display will show the distance between the sensor and an object in front of it in cm.

Schematic

Wiring of the ultrasonic sensor and the 4-digit-7-segment-display

Source Code

/*
 * An ultrasonic sensor and a 4-digit-7-segment display are used
 * the 7-segment-display shows how far an object is from the sensor in cm
 */
 
/*
 * using a common anode 4-digit-7-segment display
 * pin 22 - 28 are connected to 7 segments (A - G) of the display
 *   
 *    _ A
 *  |F  | B
 *    - G
 *  |E  | C
 *    - D
 * 
 * pin 29 is connected to the third digit (third most significant)
 * pin 30 is connected to the least significant digit
 */
const int pinA = 22;
const int pinB = 23;
const int pinC = 24;
const int pinD = 25;
const int pinE = 26;
const int pinF = 27;
const int pinG = 28;
const int C3 = 29;
const int C4 = 30;

const int trig = 42;
const int echo = 43;

float duration;
float distance;

// setup the pins connected to the 4-digit-7-segment-display
void setupDisplayPins(){
  pinMode(pinA, OUTPUT);
  pinMode(pinB, OUTPUT);
  pinMode(pinC, OUTPUT);
  pinMode(pinD, OUTPUT);
  pinMode(pinE, OUTPUT);
  pinMode(pinF, OUTPUT);
  pinMode(pinG, OUTPUT);
  pinMode(C3, OUTPUT);
  pinMode(C4, OUTPUT);
}

// display a single digit
void displayDigit(int n){
  if(n==0){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, HIGH);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, LOW);
  }else if(n==1){
    digitalWrite(pinA, LOW);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, LOW);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, LOW);    
  }else if(n==2){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, LOW);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, HIGH);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, HIGH);
  }else if(n==3){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, HIGH);
  }else if(n==4){
    digitalWrite(pinA, LOW);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, LOW);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);
  }else if(n==5){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, LOW);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);    
  }else if(n==6){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, LOW);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, HIGH);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);
  }else if(n==7){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, LOW);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, LOW);    
  }else if(n==8){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, HIGH);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);
  }else if(n==9){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);
  }else{
    digitalWrite(pinA, LOW);
    digitalWrite(pinB, LOW);
    digitalWrite(pinC, LOW);
    digitalWrite(pinD, LOW);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, LOW);    
  }
}

// displays a two digit number n on the 4-digit-7-segment display
void displayNumber(int n){
  int n2 = n;
  // if n is greater than 99, display 99:
  // if n is smaller than 0, display 0; 
  if(n>99){
     n2 = 99;
  }else if (n<0){
    n2 = 0;
  }
    
  // extract the most significant digit 
  int d1 = n2/10;  
  // extract the least significant digit 
  int d2 = n2%10;

  // display d1 in the third digit on the display
  digitalWrite(C3, LOW);
  digitalWrite(C4, HIGH);
  displayDigit(d1);
  delay(2);
  // display d2 in the last digit on the display
  digitalWrite(C3, HIGH);
  digitalWrite(C4, LOW);
  displayDigit(d2);
  delay(2);
}

void setup() {
  setupDisplayPins();
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  Serial.begin(9600);
}

void loop() {  
  // turn off the trigger pin then on:
  digitalWrite(trig, LOW);
  delay(2);
  // send out sonic waves 
  digitalWrite(trig, HIGH);
  delay(10);
  digitalWrite(trig, LOW);

  // when sound wave hits the receiver (echo), it is turned HIGH; the following gives the duration (in micros) the echo is on.
  duration = pulseIn(echo, HIGH);
  // calculate distance in cm
  distance = duration * 0.034 / 2;
  displayNumber((int)distance);
}

Part 3

Connect the fan and its motor to my Arduino. To verify that it works correctly, a push button is implemented. By default (when the program was initiated), the fan is not operating. Pressing the button changes the state of the fan (More precisely, the motor of the fan). The motor will start to operate if the button is pressed for the first time after the program is initiated. It will stop operating if the button is pressed again; pressing the button once more will restart the motor.

Schematic

Wiring of the motor and a push button

Source Code

/*
 * An ultrasonic sensor and a 4-digit-7-segment display are used
 * the 7-segment-display shows how far an object is from the sensor in cm
 * 
 * A motor with a fan blade and a push button are used
 * when the program is initiated, the motor is off; 
 * pressing the button changes the state of the motor;
 */
 
/*
 * using a common anode 4-digit-7-segment display
 * pin 22 - 28 are connected to 7 segments (A - G) of the display
 *   
 *    __ A
 * |F    | B
 *    -- G
 * |E    | C
 *    -- D
 * 
 * pin 29 is connected to the third digit (third most significant)
 * pin 30 is connected to the least significant digit
 */
const int pinA = 22;
const int pinB = 23;
const int pinC = 24;
const int pinD = 25;
const int pinE = 26;
const int pinF = 27;
const int pinG = 28;
const int C3 = 29;
const int C4 = 30;

const int trig = 42;
const int echo = 43;

const int motor = 7;
const int button = 13;

float duration;
float distance;
int speed;
boolean fanOn = false;
int oldButtonVal;
int newButtonVal;

// setup the pins connected to the 4-digit-7-segment-display
void setupDisplayPins(){
  pinMode(pinA, OUTPUT);
  pinMode(pinB, OUTPUT);
  pinMode(pinC, OUTPUT);
  pinMode(pinD, OUTPUT);
  pinMode(pinE, OUTPUT);
  pinMode(pinF, OUTPUT);
  pinMode(pinG, OUTPUT);
  pinMode(C3, OUTPUT);
  pinMode(C4, OUTPUT);
}

// display a single digit
void displayDigit(int n){
  if(n==0){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, HIGH);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, LOW);
  }else if(n==1){
    digitalWrite(pinA, LOW);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, LOW);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, LOW);    
  }else if(n==2){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, LOW);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, HIGH);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, HIGH);
  }else if(n==3){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, HIGH);
  }else if(n==4){
    digitalWrite(pinA, LOW);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, LOW);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);
  }else if(n==5){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, LOW);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);    
  }else if(n==6){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, LOW);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, HIGH);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);
  }else if(n==7){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, LOW);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, LOW);    
  }else if(n==8){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, HIGH);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);
  }else if(n==9){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);
  }else{
    digitalWrite(pinA, LOW);
    digitalWrite(pinB, LOW);
    digitalWrite(pinC, LOW);
    digitalWrite(pinD, LOW);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, LOW);    
  }
}

// displays a two digit number n on the 4-digit-7-segment display
void displayNumber(int n){
  int n2 = n;
  // if n is greater than 99, display 99:
  // if n is smaller than 0, display 0; 
  if(n>99){
     n2 = 99;
  }else if (n<0){
    n2 = 0;
  }
    
  // extract the most significant digit 
  int d1 = n2/10;  
  // extract the least significant digit 
  int d2 = n2%10;

  // display d1 in the third digit on the display
  digitalWrite(C3, LOW);
  digitalWrite(C4, HIGH);
  displayDigit(d1);
  delay(2);
  // display d2 in the last digit on the display
  digitalWrite(C3, HIGH);
  digitalWrite(C4, LOW);
  displayDigit(d2);
  delay(2);
}


void setup() {
  setupDisplayPins();
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  
  pinMode(button, INPUT_PULLUP);
  pinMode(motor, OUTPUT);
  
  Serial.begin(9600);
}

void loop() {  
  // get button value:
  oldButtonVal = digitalRead(button); // when pressed, buttonVal is 0; when released, buttonVal is 1
  
  // turn off the trigger pin then on:
  digitalWrite(trig, LOW);
  delay(2);
  // send out sonic waves 
  digitalWrite(trig, HIGH);
  delay(10);
  digitalWrite(trig, LOW);

  // when sound wave hits the receiver (echo), it is turned HIGH; the following gives the duration (in micros) the echo is on.
  duration = pulseIn(echo, HIGH);
  // calculate distance in cm
  distance = duration * 0.034 / 2;
  displayNumber((int)distance);

  // when button is pressed, change the state of the motor
  newButtonVal = digitalRead(button); 
  if(newButtonVal == 0 && newButtonVal != oldButtonVal){
    fanOn = !fanOn;
  }
  digitalWrite(motor, fanOn);
}

Part 4

The fan is controlled by a push button. By default (upon initiation of the program), the fan does not operate. Pressing the button changes the state of the motor the fan is connected to. For example, if the fan was not operating, pressing the button will turn it on; if the button is pressed again, the ran will stop operating.

The fan blade's rotational speed should be dependent on the distance read from the ultrasonic sensor. It should have four levels:

  • if the nearest object is within 10cm: fan does not operate
  • if the nearest object is 10cm ~ 20cm away: fan operates at 1/3 of its maximum rotation speed
  • if the nearest object is 20cm ~ 40cm away: fan operates at 2/3 of its maximum rotation speed
  • if the nearest object is > 40cm away: fan operates at its maximum rotation speed

Schematic

The wiring for this part is the same as Part 3

Source Code

/*
 * final project CSC270
 * Safety Fan
 * 
 * An ultrasonic sensor and a 4-digit-7-segment display are used
 * the 7-segment-display shows how far an object is from the sensor in cm
 * 
 * A motor with a fan blade and a push button are used
 * when the program is initiated, the motor is off; 
 * pressing the button changes the state of the motor;
 * 
 * The speed at which the motor (with fan blade connected to it) is dependent on the distance between the ultrasonic sensor and the object in front of it
 *  - if the object is within 10cm, the motor does not operate
 *  - if the object is 10~20cm away, the motor operates at 1/3 of its maximum speed 
 *  - if the object is 20~40cm away, the motor operates at 2/3 of its maximum speed
 *  - if the object is above 40cm away, the motor operates at its full speed;
 * 
 */
 
/*
 * using a common anode 4-digit-7-segment display
 * pin 22 - 28 are connected to 7 segments (A - G) of the display
 *   
 *    __ A
 * |F    | B
 *    -- G
 * |E    | C
 *    -- D
 * 
 * pin 29 is connected to the third digit (third most significant)
 * pin 30 is connected to the least significant digit
 */
const int pinA = 22;
const int pinB = 23;
const int pinC = 24;
const int pinD = 25;
const int pinE = 26;
const int pinF = 27;
const int pinG = 28;
const int C3 = 29;
const int C4 = 30;

const int trig = 42;
const int echo = 43;

const int motor = 7;
const int button = 13;

float duration;
float distance;
int speed;
boolean fanOn = false;
int oldButtonVal;
int newButtonVal;

// setup the pins connected to the 4-digit-7-segment-display
void setupDisplayPins(){
  pinMode(pinA, OUTPUT);
  pinMode(pinB, OUTPUT);
  pinMode(pinC, OUTPUT);
  pinMode(pinD, OUTPUT);
  pinMode(pinE, OUTPUT);
  pinMode(pinF, OUTPUT);
  pinMode(pinG, OUTPUT);
  pinMode(C3, OUTPUT);
  pinMode(C4, OUTPUT);
}

// display a single digit
void displayDigit(int n){
  if(n==0){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, HIGH);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, LOW);
  }else if(n==1){
    digitalWrite(pinA, LOW);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, LOW);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, LOW);    
  }else if(n==2){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, LOW);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, HIGH);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, HIGH);
  }else if(n==3){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, HIGH);
  }else if(n==4){
    digitalWrite(pinA, LOW);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, LOW);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);
  }else if(n==5){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, LOW);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);    
  }else if(n==6){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, LOW);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, HIGH);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);
  }else if(n==7){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, LOW);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, LOW);    
  }else if(n==8){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, HIGH);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);
  }else if(n==9){
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
    digitalWrite(pinC, HIGH);
    digitalWrite(pinD, HIGH);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, HIGH);
    digitalWrite(pinG, HIGH);
  }else{
    digitalWrite(pinA, LOW);
    digitalWrite(pinB, LOW);
    digitalWrite(pinC, LOW);
    digitalWrite(pinD, LOW);
    digitalWrite(pinE, LOW);
    digitalWrite(pinF, LOW);
    digitalWrite(pinG, LOW);    
  }
}

// displays a two digit number n on the 4-digit-7-segment display
void displayNumber(int n){
  int n2 = n;
  // if n is greater than 99, display 99:
  // if n is smaller than 0, display 0; 
  if(n>99){
     n2 = 99;
  }else if (n<0){
    n2 = 0;
  }
    
  // extract the most significant digit 
  int d1 = n2/10;  
  // extract the least significant digit 
  int d2 = n2%10;

  // display d1 in the third digit on the display
  digitalWrite(C3, LOW);
  digitalWrite(C4, HIGH);
  displayDigit(d1);
  delay(2);
  // display d2 in the last digit on the display
  digitalWrite(C3, HIGH);
  digitalWrite(C4, LOW);
  displayDigit(d2);
  delay(2);
}

// convert distance (0 - 99)cm between the sensor and an object in front of it to motor speed (0 - 255)
int distanceToSpeed(float distance){
  if(distance > 40){
    return 255;
  }else if(distance > 20){
    return 170;
  }else if(distance > 10){
    return 85;
  }else {
    return 0;
  }
}

void setup() {
  setupDisplayPins();
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  
  pinMode(button, INPUT_PULLUP);
  pinMode(motor, OUTPUT);
  
  Serial.begin(9600);
}

void loop() {  
  // get button value:
  oldButtonVal = digitalRead(button); // when pressed, buttonVal is 0; when released, buttonVal is 1
  
  // turn off the trigger pin then on:
  digitalWrite(trig, LOW);
  delay(2);
  // send out sonic waves 
  digitalWrite(trig, HIGH);
  delay(10);
  digitalWrite(trig, LOW);
  // when sound wave hits the receiver (echo), it is turned HIGH; the following gives the duration (in micros) the echo is on.
  duration = pulseIn(echo, HIGH);
  // calculate distance in cm
  distance = duration * 0.034 / 2;
  displayNumber((int)distance);

  // when button is pressed, turn on the fan;
  newButtonVal = digitalRead(button); 
  if(newButtonVal == 0 && newButtonVal != oldButtonVal){
    fanOn = !fanOn;
  }
  if(fanOn){
    Serial.println(distanceToSpeed(distance));
    analogWrite(motor, distanceToSpeed(distance));
  }else{
    analogWrite(motor, 0);
  }
}


Demonstration

Part 1 Demo

Final Demo

Final Setup

FinalSetup.jpg