Final Project – Koi Fish Table

My final project is the Koi fish table. It is basically a Laser Cutter set up. However, I wanted to use wood and acrylic to make the setup so that it would be: 1. cheaper in cost of materials; 2. easier to get materials

The coponent in this project is consist of 2 stepper motors, 3 timing belts, 3 sets of “wheels”, and several wood beams for the structure.

Here is the setup:

When it is running:

 

Here is the code:

/*This is the Code for controlling the stepper motors
 Some part of the code is adapted from the sample sketch from
 "Stepper Test code from Adafruit tutorial

This code might not work with any other shielf but
 "Adafruit Motor Shield v2"
 ----> http://www.adafruit.com/products/1438
*/



#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();

// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #1(M1 and M2) and another one to #2 (M3 and M4)
Adafruit_StepperMotor *motorX = AFMS.getStepper(200, 2);
Adafruit_StepperMotor *motorY = AFMS.getStepper(200, 1);

int motorSpeed = 100; //# rpm
int XYPosMax = 2000; //200 step per rev, 10 full rev max
int XYPosMin = 0; //whole table is a 2000 by 2000 grid



int curPosX = 0;
int curPosY = 0;

int koiDir = 0;
int koiMove = 0;

int moveX = 0;
int moveY = 0;

int yellowPin = A3;
int bluePin = A0;
int greenPin = A1;
int redPin = A2;

int yellowPre = 0;
int yellowCur = 0;
int greenPre = 0;
int greenCur = 0;
int bluePre = 0;
int blueCur = 0;
int redPre = 0;
int redCur = 0;



int threshHoldDiff = 150;





void setup() {
 // put your setup code here, to run once:
 Serial.begin(9600);
 AFMS.begin(); // create with the default frequency 1.6KHz
 //AFMS.begin(1000); // OR with a different frequency, say 1KHz
 motorX->setSpeed(motorSpeed);
 motorY->setSpeed(motorSpeed);


 yellowPre = analogRead(yellowPin);


}





void touchThePond(){
 yellowCur = analogRead(yellowPin);
 grennCur = analogRead(greenPin);
 blueCur = analogRead(bluePin);
 redCur = analogRead(redPin);

//yellow here (all same setup, different place
 if (abs(yellowCur - yellowPre) > threshHoldDiff){
 //yellow is x = 0, y = 0

moveX = curPosX;
 moveY = curPosY;
 
 motorX->step(moveX, FORWARD, MICROSTEP)
 motorY->step(moveY, BACKWARD, MICROSTEP)
 }

//blue

//green

//red
}





void moveKoiRand() {
 //First, pick a direction
 //Then decide how much wanna go
 koiDir = random(0, 4); //0 = +X, 1 = -X, 2 = +Y, 3 = -Y
 koiMove = random(50, 401); //small "steps" to mimic fish movement
//
// Serial.print("koiDir = ");
// Serial.print(koiDir);
// Serial.print("; koiMove = " );
// Serial.println(koiMove);
//
// Serial.print("curPosX = ");
// Serial.print(curPosX);
// Serial.print("curPosY = ");
// Serial.println(curPosY);

if (koiDir == 0) {

//check the legality of the position first;
 if ((curPosX + koiMove) >= XYPosMax) {
 moveX = XYPosMax - curPosX; //move to the edge
 }
 else {
 moveX = koiMove;
 }

// Serial.print("in case 0, moveX= ");
// Serial.print(moveX);
 motorX->step(moveX, BACKWARD, MICROSTEP); // moving +X is

curPosX += moveX; //update the new position data;
// Serial.print("in case 0, curPosX= ");
// Serial.println(curPosX);
 }

if (koiDir == 1) {

if ((curPosX - koiMove) <= XYPosMin) {
 moveX = curPosX;
 }
 else {
 moveX = koiMove;
 }

// Serial.print("in case 1, moveX= ");
// Serial.print(moveX);
 motorX->step(moveX, FORWARD, MICROSTEP);

curPosX -= moveX;
// Serial.print("in case 1, curPosX= ");
// Serial.println(curPosX);
 }



if (koiDir == 2) {
 if ((curPosY + koiMove) >= XYPosMax) {
 moveY = XYPosMax - curPosY; //move to the edge
 }
 else {
 moveY = koiMove;
 }
//
// Serial.print("in case 2, moveY= ");
// Serial.print(moveY);
 motorY->step(moveY, FORWARD, MICROSTEP);

curPosY += moveY;
// Serial.print("in case 2, curPosY= ");
// Serial.println(curPosY);
 }

if (koiDir == 3) {
 if ((curPosY - koiMove) <= XYPosMin) {
 moveY = curPosY;
 }
 else {
 moveY = koiMove;
 }

// Serial.print("in case 3, moveY= ");
// Serial.print(moveY);
 motorY->step(moveY, BACKWARD, MICROSTEP);

curPosY = curPosY - moveY;

// Serial.print("in case 3, curPosY= ");
// Serial.println(curPosY);
 }

}





void loop() {
 // put your main code here, to run repeatedly:
 Serial.println("Microstep steps");
 moveKoiRand();


}

 

Design of the “Wheel”:

General Idea/Assembly

 

 

For the Koi fish holder part

 

Reflection:

The really hard part of this project is to make the mechanical setup. I spent more than a week working on solidworks. However, the setup is too big and not as percise as I hoped it would be. Therefore, there are a lot of problem while working in the wood shop initially. Later I gave up on following soliworks, and just try and test laser cutting and wood working.

Another part that is complicated is to make the stepper work. The Arduino shield is nice, for controlling the stepper. The libaray it came with helps me to reduced a lot of time for me trying to figure out how to work with stepper (even though it still took a long time for me to understand how stepper works). The other problem that I faced is that the stepper doesn’t come with avaliable datasheet (I coudn’t find anything). However, the shield was nice enough that I tried out a few different voltage input using a controllable power output for the stepper. Finally, I found out that the stepper needs 1.5A at 5V which is a lot higher than normal power supply. At last I used 2.4A at around 8V to power the stepper to make sure it can over come the friction it might experience.

The problem that I didn’t really solve in this project is how to change the stepper speed. Even the Adafruit library include speed settings, the stepper speed couldn’t be changed for some reason.

If I were to do this project again, I will add a set of caliberation setting. I will mount limit switches on the zero of X and Y axis. So I don’t need to hand calibrate to zero position everytime it restarts. However, that need me to figure out how to program the stepper to move without having to tell it how much it needs to move.

 

 

Koi Fish Coffee Table

This project is going to be a installation for the size about a side table/coffee table. The top of the installation would be in glass/clear acylic where things can be put on like a real coffee table.

The table installation would be able to interact with different objects been put on the table based on the temperature. The koi fish would swim in a random pattern (similar to a real koi fish). When someone sits at the table and put something on the table top, if the thing is hot like coffee or tea, the koi fish will swim away from the object. If the thing is cold, like soda or snacks, the koi fish will swim towards the project, and swim around for a while.

Personally, I am very fond of the east asian style gardens (Chinese and Japanese). The project is to make the living room more interesting for people that doesn’t have enought space or time to take care of a koi pond garden. Kind of like the idea of karesansui,the Japanese Zen Garden, which is very artistic and easier to take care of. In the modern urban settings, it is really hard to have a big enough tank/pond body of water for actual koi fishes. However, a koi pond that does not require water or big space would be ideal.

 

Hardware:

  • 2 or 3 stepper motor (maybe more)
  • Some non real koi fish (Wood carved would be awesome, 3D printed is also acceptable I think)
  • A couple of timing belts (or one really long one), and pulleys
  • tiny camera/IR camera for tempertature detection/ Motion Detector?
  • Some white sand (For appearence, not super necessary for mechanical part)
  • A couple of strong magnets
  • I might need more things but I can’t think of it right now….
  • (basically it is the x and y axis for a 3d printer/laser cutter)

 

Software:

  •  I need software to work with the camera to read temperature
  • I need some library to work with the stepper motor

 

Order of Construction and Testing:

  1. Make the stepper motor work
  2. Figure out how to detect temperature
  3. Construct the table with 8020
  4. Install the stepper motor and timing belt to test
  5. Make the servo work and behaves like a koi fish
  6. Install magnets and stick the koi on the moving part
  7. Make the table look like an actual aquarium/pond
  8. Work with a couple of servos to make koi more realistic

Spooky Scary Mask – Final

 

This is the final project of the Spooky Scary Mask, if you want to review the first part of the prototyping (the distance detector, how to play sound), please click here.

This part of the spooky scary mask, the main focus is how to work with the solinoid/fluid pumps and the mechanical part of the project. The main goal for the mechanical part is to make the fake blook flush into the mask, to create the bloody scary effect.

Here is the fritzing sketch for this somewhat-working demo, whichi is not a whole lot more complicated than the previous one:

 

Here is the code, not much have changed from prototype part 1:

//JeanZhang_yihanz
//The Bloody Scary Mask - Part 1
//This code contains code and resources from this webpage:
//http://randomnerdtutorials.com/complete-guide-for-ultrasonic-sensor-hc-sr04/


//Set up the pins
const int trigPin = 11; //Trig - green Jumper - digital 
const int echoPin = 12; //Echo - yellow Jumper - pwm
const int soundPin = 5;

const int solinoid1 = 9;
const int solinoid2 = 8;

long duration, cm, inches;


//This is the function for a spooky sound (doesn't have to be exactly like this)
void scarySound() {
 for (int i = 100; i < 1000 ; i+= 20) {
 Serial.println(i);
 tone(soundPin, i);
 delay(50);
 }
 for (int i = 1000; i > 100; i-=20) {
 Serial.println(i);
 tone(soundPin, i);
 delay(50);
 }
 noTone(soundPin); // stop the sound after the trigger
}


void setup() {
 //Serial Port begin
 Serial.begin (9600);
 
 //Define inputs and outputs
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);
 pinMode(soundPin, OUTPUT);
 pinMode(solinoid1, OUTPUT);
 pinMode(solinoid2, OUTPUT);
}
 
void loop()
{
 digitalWrite(solinoid1, LOW);
 digitalWrite(solinoid2, LOW);
 
 
 // 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;
 inches = (duration/2) / 74; 
 
 Serial.print(inches);
 Serial.print("in, ");
 Serial.print(cm);
 Serial.print("cm");
 Serial.println();

//if the person is close enough, things will be triggered
 if (cm < 20){
 digitalWrite(solinoid1, HIGH);
 digitalWrite(solinoid2, HIGH);
 scarySound();
 }
 delay(250);
}

 

Reflection:

The coding and wiring part of the second half is not hard to figure out. However , the mechanical part is really hard to be done. Since I bought the mask from a Halloween store, and this is a part of a kid costume. The bloody “heart” is made for the force that can be applied by human hand. In this case however, the solinoids can’t apply

 

Spooky Scary Mask – Part 1

This is the first part of the Holloween project – the Spooky Scary Mask. There is a sonic detector to monitor how close people are, when people are close enough (about 20cm), the sound effect will go off and the “blood ball” will be squeeze , and the mask will spin randomly as if the ghost is giggling and laughing at the spooked person.

 

How the project would work is that there will be a motor connected to the blood splashing mask that makes it turn and spin. The solinoids will be actuated and squeeze the ball. There is also a sonic detector to detect how close people are from the setup.

Here is what I have for the first part of the project. Since I already familierized myself with motor and solinoids in the previous projects, the main focus on this part is about the soinc sensor and the sound.

 

Here is the sketch and the code for the setup:

Code:

//JeanZhang_yihanz
//The Bloody Scary Mask - Part 1
//This code contains code and resources from this webpage:
//http://randomnerdtutorials.com/complete-guide-for-ultrasonic-sensor-hc-sr04/



//Set up the pins
const int trigPin = 11; //Trig - green Jumper - digital 
const int echoPin = 12; //Echo - yellow Jumper - pwm
const int soundPin = 5;

long duration, cm, inches;



//This is the function for a spooky sound (doesn't have to be exactly like this)
void scarySound() {
 for (int i = 100; i < 1000 ; i+= 20) {
 Serial.println(i);
 tone(soundPin, i);
 delay(50);
 }
 for (int i = 1000; i > 100; i-=20) {
 Serial.println(i);
 tone(soundPin, i);
 delay(50);
 }
 noTone(soundPin); // stop the sound after the trigger
}


void setup() {
 //Serial Port begin
 Serial.begin (9600);
 
 //Define inputs and outputs
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);
 pinMode(soundPin, OUTPUT);
}
 
void loop()
{
 
 
 // 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;
 inches = (duration/2) / 74; 
 
 Serial.print(inches);
 Serial.print("in, ");
 Serial.print(cm);
 Serial.print("cm");
 Serial.println();

//if the person is close enough, things will be triggered
 if (cm < 20){
 scarySound();
 }
 
 delay(250);
}

 

 

Reflection:

Even though this seems really easy, it took me quite a long time to figure out that several libraries for the sonic detector is not compatible with the tone() function for arduino. For this paticular problem, even though there is not really any problem with the code, the IDE would not complie. And shows error is like this:

Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':

(.text+0x0): multiple definition of `__vector_7'

libraries\NewPing\NewPing.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

I spent quite sometime online to see if there is anything to do to fix this problem, which I failed to do. At the end, I have to switch to another way to make the sensor work (without using any library).

Clapping Hands

This project is about using motion to express emotion. Here I chose the emotion of happiness, related to the motion of clapping hands. So here is my tiny robot “Pat”.

The main components of this setup are solenoids, potentiometer, and pushbutton. Here, the solenoids represents the hands; the button represents praising words; the potentiometer represents how flattered Pat  is.

When Pat got praised (the button is pushed), he starts to clap his solenoid hands. If he is more flattered than normal (turn the potentiometer to one side), he will be happier and clap his hands faster; if he is not so flattered (turn the potentiometer to the other side), he will slow down the clapping speed back to normal.

 

If you want to create your clapping “Pat”, here is the code and sketch to help you:

Arduino Code File: Clapping Pat – Code

Fritzing Sketch: Clapping Pat – Sketch