We created a flapping bird toy that would move and chirp depending on how close you got to it. We encountered a couple issues with the performance of our device. The distance sensor stopped working and while sometimes being within the range of it would trigger the flapping and chirping, to the children, it wasn’t clear that a movement event was the cause of the bird’s reaction. Throughout the two hours we demoed, the hinges started falling off and the motor inside of the base came off. However, we had a previous version of our design without the electronics and we found the children were much more interested in that version.
Mechanical Design

The moving wings and beak are designed to be operated by pulleys that are strung throughout the hollow body. The beak uses a small spring to keep it in the open position, while the string is able to pull it closed.

The yellow string controls the beak, while the green strings control the wings. In the box, two servos are able to activate them.
After it was working, we decorated it to really stand out.

Software Design
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | /* * created by Rui Santos, https://randomnerdtutorials.com * * Complete Guide for Ultrasonic Sensor HC-SR04 * Ultrasonic sensor Pins: VCC: +5VDC Trig : Trigger (INPUT) - Pin11 Echo: Echo (OUTPUT) - Pin 12 GND: GND */ #include <Servo.h> #define SPEAKER 3 #define SERIAL Servo bird; int trigPin = 11; // Trigger int echoPin = 12; // Echo long duration, cm, inches; long next_output_time_motor = 0; long next_output_time_sound = 0; int motor_state = LOW; void setup() { //Serial Port begin Serial.begin (9600); bird.attach(4); //Define inputs and outputs pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); #ifdef SERIAL Serial.begin(9600); #endif pinMode(SPEAKER,OUTPUT); } void loop() { long now = micros(); // The sensor is triggered by a HIGH pulse of 10 or more microseconds. // Give a short LOW pulse beforehand to ensure a clean HIGH pulse: digitalWrite(trigPin, LOW); delayMicroseconds(5); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Read the signal from the sensor: a HIGH pulse whose // duration is the time (in microseconds) from the sending // of the ping to the reception of its echo off of an object. pinMode(echoPin, INPUT); duration = pulseIn(echoPin, HIGH); // Convert the time into a distance cm = (duration/2) / 29.1; // Divide by 29.1 or multiply by 0.0343 inches = (duration/2) / 74; // Divide by 74 or multiply by 0.0135 Serial.print(inches); Serial.print("in, "); Serial.print(cm); Serial.print("cm"); Serial.println(); if (now >next_output_time_motor && inches < 13 && motor_state){ bird.write(0); next_output_time_motor = now + (1300-((13-inches))*100); motor_state = !motor_state; } if (now > next_output_time_motor && inches < 13 && !motor_state){ bird.write(180); next_output_time_motor = now + (1300-((13-inches))*100); motor_state = !motor_state; } if (now > next_output_time_sound && inches < 13){ int chirpnum = random(0,4); Serial.println(chirpnum); if (chirpnum == 0){ chirp(); } if (chirpnum == 1){ chirp2(); } if (chirpnum == 2){ chirp3(); } if (chirpnum == 3){ chirp4(); } next_output_time_sound = now + 20; } } void chirp() { // Bird chirp for(uint8_t i=190; i>170; i-=2) playTone(i,9); } void chirp2() { // Bird chirp for(uint8_t i=250; i>220; i-=1) playTone(i,9); } void chirp3() { // Bird chirp for(uint8_t i=180; i<200; i++ ) playTone(i,9); } void chirp4() { // Bird chirp for(uint8_t i=250; i>150; i--) playTone(i,9); for(uint8_t i=180; i<250; i++) playTone(i,9); } // play tone on a piezo speaker: tone shorter values produce higher frequencies // which is opposite beep() but avoids some math delay - similar to code by Erin Robotgrrl void playTone(uint16_t tone1, uint16_t duration2) { if(tone1 < 50 || tone1 > 15000) return; // these do not play on a piezo for (long i = 0; i < duration2 * 1000L; i += tone1 * 2) { digitalWrite(SPEAKER, HIGH); delayMicroseconds(tone1); digitalWrite(SPEAKER, LOW); delayMicroseconds(tone1); } } |
Leave a Reply
You must be logged in to post a comment.