For tech demo 3 I created a belt-driven fan. To make the system work, a stepper motor rotates a set of gears which drives a belt to rotate an axle that is attached to the fan blades.
My code is a minimalistic version of the ServorSweep demo we used in class.
#define DIR_PIN 2
#define STEP_PIN 3
#define ENABLE_PIN 4
void setup(void)
{
// Initialize the stepper driver control pins to output drive mode.
pinMode(DIR_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
pinMode(ENABLE_PIN, OUTPUT);
// Drive the /ENABLE pin low to keep the motor always energized.
digitalWrite(ENABLE_PIN, LOW);
// Initialize the serial UART at 9600 bits per second.
Serial.begin(9600);
}
void rotate_stepper(int steps, float speed)
{
int dir = (steps > 0)? HIGH:LOW;
digitalWrite(DIR_PIN, dir);
int pulses = abs(steps);
unsigned long wait_time = 500000/speed;
unsigned int msec = wait_time / 1000;
unsigned int usec = wait_time - (1000*msec);
for(int i = 0; i < pulses; i++) { digitalWrite(STEP_PIN, HIGH); if (msec > 0) delay(msec);
if (usec > 0) delayMicroseconds(usec);
digitalWrite(STEP_PIN, LOW);
if (msec > 0) delay(msec);
if (usec > 0) delayMicroseconds(usec);
}
}
void loop(void)
{
rotate_stepper(-1000, 250.0);
}
I tried to create a small turtle that would wave it’s little flippers. It did not exactly work as planned. Firstly, it became a more abstract idea of a turtle (a more futuristic interpretation). Although the laser cutting worked fine, the physical motion part was awkward and stunted. I believe that to create a better system for movement, I would need a gear system to allow it to work properly.
#define DIR_PIN 2 // The direction pin controls the direction of stepper motor rotation. #define STEP_PIN 3 // Each pulse on the STEP pin moves the stepper motor one angular unit. #define ENABLE_PIN 4 // Optional control of the driver power. void setup(void) { pinMode(DIR_PIN, OUTPUT); pinMode(STEP_PIN, OUTPUT); pinMode(ENABLE_PIN, OUTPUT); digitalWrite(ENABLE_PIN, LOW); Serial.begin(9600); } void rotate_stepper(int steps, float speed) { // Configure the direction pin on the stepper motor driver based on the sign // of the displacement. int dir = (steps > 0)? HIGH:LOW; digitalWrite(DIR_PIN, dir); // Find the positive number of steps pulses to emit. int pulses = abs(steps); // Compute a delay time in microseconds controlling the duration of each half // of the step cycle. // microseconds/half-step = (1000000 microseconds/second) * (1 step/2 half-steps) / (steps/second) unsigned long wait_time = 500000/speed; // The delayMicroseconds() function cannot wait more than 16.383ms, so the // total delay is separated into millisecond and microsecond components. This // increases the range of speeds this function can handle. unsigned int msec = wait_time / 1000; unsigned int usec = wait_time - (1000*msec); // Print a status message to the console. Serial.print("Beginning rotation of "); Serial.print(steps); Serial.print(" steps with delay interval of "); Serial.print(msec); Serial.print(" milliseconds, "); Serial.print(usec); Serial.print(" microseconds.\n"); // Loop for the given number of step cycles. The driver will change outputs // on the rising edge of the step signal so short pulses would work fine, but // this produces a square wave for easier visualization on a scope. for(int i = 0; i < pulses; i++) { digitalWrite(STEP_PIN, HIGH); if (msec > 0) delay(msec); if (usec > 0) delayMicroseconds(usec); digitalWrite(STEP_PIN, LOW); if (msec > 0) delay(msec); if (usec > 0) delayMicroseconds(usec); } } // ================================================================================ // Run one iteration of the main event loop. The Arduino system will call this // function over and over forever. void loop(void) { // Begin the motion sequence with a few back-and-forth movements at faster and faster speeds. rotate_stepper( 60, 30.0); rotate_stepper( -60, 30.0); delay(1000); }]]>
This is a prototype for a drawing machine that uses one servo. The gears were successfully calibrated to work as intended but I have had trouble setting the center gear (that is powered by the servo) in place, to rotate the two secondary gears (that would move the pantograph). The idea was that while the pen on the pantograph is moving, so would the canvas that it would be drawing on. I thought it would be interesting to see what kind of geometry this double rotational movement would create. Unfortunately, it is not complete at the current state but I will continue to work on this.
]]>
For this assignment, I created a BusyBox using laser cut gears and box. In essence, a BusyBox is an object/mechanism that appears to be doing work but in actuality is doing absolutely nothing (very descriptive of myself). Using the ServoSweeper, an LED, a switch, and very basic Arduino Code, I created a mechanism activated by the switch that turns this machine one, where the sweeper starts the motion of the big gear and locks into the smaller ones, activating the system. An LED turns on signify the machine is on/busy, even though it really is doing nothing. An idea like this could even me practical for small children, who would be enticed by the distracting moving gears and light, and would also fail to notice that really nothing is happening— they would simply enjoy being able to control the system with the switch.
It is a nothing-machine.
//ZAIN ISLAM-HASHMI ASSIGNEMNT 3 #include <Servo.h> Servo sweeper; int pos = 0; int delspeed1; int delspeed2; void setup() { // put your setup code here, to run once: sweeper.attach(9); } void loop() { delspeed1 = random (15, 75); delspeed2 = random (15, 75); // put your main code here, to run repeatedly: for (pos = 5; pos <=175; pos +=1) { sweeper.write(pos); delay(delspeed1); } for (pos = 175; pos >= 5; pos -=1) { sweeper.write(pos); delay(delspeed2); } }]]>
A basic set of eight small gears orbiting one larger gear powered by a stepper motor and controlled by an ultrasonic sensor. As the range of the sonar pulse increases, so does the speed of the busy box.
Made for the Tech Demo 3 – Mechanics
Code as follows (Modified from my Tech Demo 2 code):
#define TRIG_PIN 8
#define ECHO_PIN 7
#define MAX_DISTANCE 450
#define SOUND_SPEED 34000
#define TIMEOUT (2 * MAX_DISTANCE * 1000000)/SOUND_SPEED
#define DIR_PIN 2 // The direction pin controls the direction of stepper motor rotation.
#define STEP_PIN 3 // Each pulse on the STEP pin moves the stepper motor one angular unit.
#define ENABLE_PIN 4 // Optional control of the driver power.
void setup()
{
pinMode(TRIG_PIN, OUTPUT);
digitalWrite(TRIG_PIN, LOW);
pinMode(ECHO_PIN, INPUT);
pinMode(DIR_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
pinMode(ENABLE_PIN, OUTPUT);
digitalWrite(ENABLE_PIN, LOW);
Serial.begin(9600);
}
long ping_sonar(void)
{
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
return pulseIn(ECHO_PIN, HIGH, TIMEOUT);
}
void rotate_stepper(int steps, float speed)
{
// Configure the direction pin on the stepper motor driver based on the sign
// of the displacement.
int dir = (steps > 0)? HIGH:LOW;
digitalWrite(DIR_PIN, dir);
// Find the positive number of steps pulses to emit.
int pulses = abs(steps);
// Compute a delay time in microseconds controlling the duration of each half
// of the step cycle.
// microseconds/half-step = (1000000 microseconds/second) * (1 step/2 half-steps) / (steps/second)
unsigned long wait_time = 500000/speed;
// The delayMicroseconds() function cannot wait more than 16.383ms, so the
// total delay is separated into millisecond and microsecond components. This
// increases the range of speeds this function can handle.
unsigned int msec = wait_time / 1000;
unsigned int usec = wait_time – (1000*msec);
// Print a status message to the console.
Serial.print(“Beginning rotation of “);
Serial.print(steps);
Serial.print(” steps with delay interval of “);
Serial.print(msec);
Serial.print(” milliseconds, “);
Serial.print(usec);
Serial.print(” microseconds.\n”);
// Loop for the given number of step cycles. The driver will change outputs
// on the rising edge of the step signal so short pulses would work fine, but
// this produces a square wave for easier visualization on a scope.
for(int i = 0; i < pulses; i++) { digitalWrite(STEP_PIN, HIGH); if (msec > 0) delay(msec);
if (usec > 0) delayMicroseconds(usec);
digitalWrite(STEP_PIN, LOW);
if (msec > 0) delay(msec);
if (usec > 0) delayMicroseconds(usec);
}
}
void loop()
{
long duration = ping_sonar();
if (duration > 0) {
float distance = (duration * 1e-6 * SOUND_SPEED) / 2;
Serial.print(“Ping: “);
Serial.print(duration);
Serial.print(” usec Distance: “);
Serial.print(distance);
Serial.println(” cm”);
int gearSpeed = min(300, max(distance*2, 100));
rotate_stepper(1000, gearSpeed);
} else {
Serial.println(“No ping.”);
}
delay(30);
}
// Import libraries. #include <Servo.h> // The wiring assignment. const int SERVO_PIN = 9; int isObstaclePin = 7; // This is our input pin int isObstacle = HIGH; // HIGH MEANS NO OBSTACLE Servo wiggling_servo; void setup() { // Initialize the serial UART at 9600 bits per second. Serial.begin(9600); // Initialize the Servo object to use the given pin for output. wiggling_servo.attach(SERVO_PIN); wiggling_servo.write(0); //Infrared setup pinMode(isObstaclePin, INPUT); Serial.begin(9600); } void loop() { checkSensor(); } void checkSensor() { isObstacle = digitalRead(isObstaclePin); Serial.print("is obstacle"); Serial.println(isObstacle); if(isObstacle == HIGH){ wiggling_servo.write(0); } if(isObstacle == LOW){ wiggling_servo.write(45); } }]]>
For tech demo three I designed, drafted and laser cut the parts of a car, and then attached a DC motor to a fan to propel it into action! Thanks to Zack for helping me develop the design of the car. Took a few iterations of the size and shape of the fan for the car to move. In the end I used a photo light sensor as input, and wrote the code so that the blades of the fan would rotate depending on how much light the sensor was receiving.
The code is pretty simple, and is attached below:
int sensorPin = A0; // input pin int sensorValue = 0; void setup() { pinMode(6, OUTPUT); pinMode(7, OUTPUT); Serial.begin(9600); } void loop() { sensorValue = analogRead(sensorPin); int power = map(sensorValue, 800,900,0,255); if (power > 255) power = 255; if (power < 0) power = 0; digitalWrite(6,LOW); analogWrite(7,power); Serial.println(power); //to check sensor output Serial.print("SensorValue: "); Serial.println(sensorValue); }]]>
For this assignment, I studied the behavior of time and created a device that is a simple timer/clock. Using the Arduino, I created a program that measures 30 seconds in human time, and upon reaching its goal, blinks the 2 LEDs with great joy at reaching its goal [and finishing this assignemnt] (and then quickly setting back to repeat this task over and over again).
// Import libraries. #include <Servo.h></pre> // ================================================================================ // Define constant values and global variables. // The wiring assignment. #define LED1PIN 5 #define LED2PIN 6 #define SERVO_PIN 9 #define BLINKDELAY 100 // in milliseconds int CurrentAngle; // Create an object to control the servo by declaring it. The Servo C++ class // is defined in the Servo library. Servo servo; // ================================================================================ // Configure the hardware once after booting up. This runs once after pressing // reset or powering up the board. void setup() { // Initialize the serial UART at 9600 bits per second. Serial.begin(9600); // Initialize the Servo object to use the given pin for output. servo.attach(SERVO_PIN); } // ================================================================================ // Linear servo movement function. This will step from the start angle to the // end angle as requested. This emits servo updates at a constant rate. It // does not return until the movement is complete. // // start - angle in degrees // end - angle in degrees // speed - optional argument, speed in degrees/sec // void linear_move(int start, int end, float speed = 6.0) { // Specify the number of milliseconds to wait between updates. const int interval = 20; // Compute the size of each step in degrees. Note the use of float to capture // fractional precision. The constant converts speed units from milliseconds // to seconds: deg/step = (deg/sec) * (sec/msec) * (msec/step) float step = speed * 0.001 * interval; // Declare a float variable to hold the current servo angle. float angle = start; // Begin a do-loop. This always executes the body at least once, and then // iterates if the while condition is met. do { servo.write(angle); // update the servo output delay(interval); // pause for the sampling interval if (end >= start) { angle += step; // movement in the positive direction if (angle > end) angle = end; } else { angle -= step; // movement in the negative direction if (angle < end) angle = end; } } while (angle != end); // Update the servo with the exact endpoint before returning. servo.write(end); } // ================================================================================ void loop() { for (int i = 0; i < 10; i++) { CurrentAngle = 180; linear_move(0, CurrentAngle); if (CurrentAngle = 180) { for (int i = 0; i < 3; i++) { digitalWrite(LED1PIN, HIGH); // turn LED1 on delay(BLINKDELAY); digitalWrite(LED1PIN, LOW); // turn LED1 off digitalWrite(LED2PIN, HIGH); // turn LED2 on delay(BLINKDELAY); digitalWrite(LED2PIN, LOW); // turn LED2 off delay(BLINKDELAY); } } linear_move(180, 0, 600); CurrentAngle = 0; } }]]>